diff --git a/.gitattributes b/.gitattributes
index 1185e15..47ea9b3 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -5,7 +5,7 @@
.editorconfig export-ignore
.gitattributes export-ignore
.gitignore export-ignore
-.php_cs export-ignore
.scrutinizer.yml export-ignore
-.travis.yml export-ignore
-phpunit.xml export-ignore
+.styleci.yml export-ignore
+phpstan.neon.dist export-ignore
+phpunit.xml.dist export-ignore
diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml
index a1eb104..87ed63d 100644
--- a/.github/FUNDING.yml
+++ b/.github/FUNDING.yml
@@ -1,2 +1,3 @@
+github: yajra
patreon: yajra
custom: https://www.paypal.me/yajra
diff --git a/.github/workflows/tests.yml b/.github/workflows/continuous-integration.yml
similarity index 72%
rename from .github/workflows/tests.yml
rename to .github/workflows/continuous-integration.yml
index 85e883a..49f05ab 100644
--- a/.github/workflows/tests.yml
+++ b/.github/workflows/continuous-integration.yml
@@ -1,23 +1,25 @@
-name: tests
+name: Continuous Integration
on:
push:
+ branches:
+ - master
+ - '*.x'
pull_request:
schedule:
- cron: '0 0 * * *'
jobs:
tests:
-
runs-on: ubuntu-latest
strategy:
fail-fast: true
matrix:
- php: [7.3, 7.4, 8.0]
- stability: [prefer-lowest, prefer-stable]
+ php: [8.2, 8.3, 8.4]
+ stability: [prefer-stable]
- name: PHP ${{ matrix.php }} - ${{ matrix.stability }}
+ name: PHP ${{ matrix.php }} - STABILITY ${{ matrix.stability }}
steps:
- name: Checkout code
@@ -27,7 +29,6 @@ jobs:
uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php }}
- extensions: dom, curl, libxml, mbstring, zip, pcntl, pdo, sqlite, pdo_sqlite, gd, memcached
tools: composer:v2
coverage: none
@@ -42,4 +43,4 @@ jobs:
command: composer update --${{ matrix.stability }} --prefer-dist --no-interaction --no-progress
- name: Execute tests
- run: vendor/bin/phpunit --verbose
+ run: vendor/bin/phpunit
diff --git a/.github/workflows/pint.yml b/.github/workflows/pint.yml
new file mode 100644
index 0000000..c07577f
--- /dev/null
+++ b/.github/workflows/pint.yml
@@ -0,0 +1,33 @@
+name: PHP Linting
+
+on:
+ pull_request:
+ push:
+ branches:
+ - master
+ - '*.x'
+
+jobs:
+ pint:
+ name: Pint
+
+ runs-on: ubuntu-latest
+
+ permissions:
+ contents: write
+ pull-requests: write
+
+ steps:
+ - uses: actions/checkout@v4
+ with:
+ ref: ${{ github.head_ref }}
+
+ - name: "laravel-pint"
+ uses: aglipanci/laravel-pint-action@latest
+ with:
+ preset: laravel
+ verboseMode: true
+
+ - uses: stefanzweifel/git-auto-commit-action@v5
+ with:
+ commit_message: "fix: pint :robot:"
diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml
new file mode 100644
index 0000000..bae8b28
--- /dev/null
+++ b/.github/workflows/stale.yml
@@ -0,0 +1,22 @@
+name: Close inactive issues
+on:
+ schedule:
+ - cron: "30 1 * * *"
+
+jobs:
+ close-issues:
+ runs-on: ubuntu-latest
+ permissions:
+ issues: write
+ pull-requests: write
+ steps:
+ - uses: actions/stale@v5
+ with:
+ days-before-issue-stale: 30
+ days-before-issue-close: 7
+ stale-issue-label: "stale"
+ stale-issue-message: "This issue is stale because it has been open for 30 days with no activity."
+ close-issue-message: "This issue was closed because it has been inactive for 7 days since being marked as stale."
+ days-before-pr-stale: -1
+ days-before-pr-close: -1
+ repo-token: ${{ secrets.GITHUB_TOKEN }}
diff --git a/.github/workflows/static-analysis.yml b/.github/workflows/static-analysis.yml
new file mode 100644
index 0000000..4dccad0
--- /dev/null
+++ b/.github/workflows/static-analysis.yml
@@ -0,0 +1,39 @@
+name: Static Analysis
+
+on:
+ push:
+ branches:
+ - master
+ - '*.x'
+
+ pull_request:
+
+ schedule:
+ - cron: '0 0 * * *'
+
+jobs:
+ static-analysis-phpstan:
+
+ name: Source Code
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@v4
+
+ - name: Setup PHP
+ uses: shivammathur/setup-php@v2
+ with:
+ php-version: 8.2
+ tools: composer:v2
+ coverage: none
+
+ - name: Install dependencies
+ uses: nick-fields/retry@v3
+ with:
+ timeout_minutes: 5
+ max_attempts: 5
+ command: composer update --prefer-stable --prefer-dist --no-interaction --no-progress
+
+ - name: Run Static Analysis
+ run: vendor/bin/phpstan
diff --git a/.gitignore b/.gitignore
index df0e1ea..c2e4bf9 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,3 +2,4 @@
/coverage
composer.phar
composer.lock
+/.phpunit.cache/test-results
diff --git a/.php_cs b/.php_cs
deleted file mode 100644
index e8c5a2a..0000000
--- a/.php_cs
+++ /dev/null
@@ -1,77 +0,0 @@
-finder(DefaultFinder::create()->in(__DIR__))
- ->fixers($fixers)
- ->level(FixerInterface::NONE_LEVEL)
- ->setUsingCache(true);
diff --git a/.styleci.yml b/.styleci.yml
new file mode 100644
index 0000000..0285f17
--- /dev/null
+++ b/.styleci.yml
@@ -0,0 +1 @@
+preset: laravel
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 99a5bba..04d08aa 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,775 +1,18 @@
# Laravel DataTables Html Plugin.
-[](https://packagist.org/packages/yajra/laravel-datatables-html)
-[](https://packagist.org/packages/yajra/laravel-datatables-html)
-[](https://travis-ci.org/yajra/laravel-datatables-html)
-[](https://packagist.org/packages/yajra/laravel-datatables-html)
-[](https://packagist.org/packages/yajra/laravel-datatables-html)
-
## CHANGELOG
-### v4.41.1 - 03-05-2022
-
-- Fix Field::attr() doc block.
-
-### v4.41.0 - 10-07-2021
-
-- Add exportFormat method. #160
-
-### v4.40.0 - 10-04-2021
-
-- Add method getTableId() #159
-
-### v4.39.1 - 09-12-2021
-
-- Fix doc block and add array as acceptable Column editField value.
-
-### v4.39.0 - 09-12-2021
-
-- Add missing select field options as of Editor 1.5.4.
-
-### v4.38.0 - 06-20-2021
-
-- Fix fetching of editor table #158
-- Add method to get all editors instances.
-- Add method to get dataTable options array.
-- Set serverSide and processing option as true by default.
-
-### v4.37.0 - 05-17-2021
-
-- Implement authorizations on Editor builder.
-
-### v4.36.3 - 04-23-2021
-
-- Fix conflicts with createInline button. Use render instead of altering the data.
-
-### v4.36.2 - 03-19-2021
-
-- Fix exportable flag, should be false.
-
-### v4.36.1 - 12-05-2020
-
-- Fix adding of class on Select plugin / extension. [#154]
-
-### v4.36.0 - 11-14-2020
-
-- Add drawCallbackWithLivewire api.
-- Solution as per issue https://github.com/yajra/laravel-datatables/issues/2401.
-
-### v4.35.2 - 11-14-2020
-
-- Add missing button options as per [docs](https://datatables.net/reference/option/#buttons).
-
-### v4.35.1 - 11-03-2020
-
-- Add missing upload field options as per doc. [#152]
-
-### v4.35.0 - 11-03-2020
-
-- Add formatted column factory. [#147]
-
-### v4.34.0 - 10-31-2020
-
-- Add support for search panes extension. [#137]
-
-### v4.33.0 - 10-30-2020
-
-- Make LaravelDataTables javascript namespace configurable. [#145], credits to @om3rcitak
-
-### v4.32.0 - 10-10-2020
-
-- Add function argument to override the default options from php scripts. [#144]
-
-### v4.31.0 - 10-09-2020
-
-- Add button customize option value. [#142], credits to @gredimano
-- Fix https://github.com/yajra/laravel-datatables/issues/1541
-- Add template and method to wrap scripts with a function. [#143]
-
-### v4.30.3 - 10-06-2020
-
-- Wait for DOM before executing script using jQuery [#138]
-- Fix [#133]
-
-### v4.30.2 - 10-06-2020
-
-- Fix chrome bfcache issue with editor. [#139], credits to @jiwom
-- Allow using callbacks as a data value. [#127], credits to @mgralikowski
-
-### v4.30.1 - 09-29-2020
-
-- Fix [#134] laravel 8 dependencies [#135], credits to @dyanakiev.
-
-### v4.30.0 - 06-18-2020
-
-- Add button align property setter.
-
-### v4.29.0 - 06-17-2020
-
-- Add column responsive priority setter. [#131], credits to @SamDeimos.
-
-### v4.28.0 - 06-10-2020
-
-- Allow eloquent builder instance on BelongsTo model field.
-
-### v4.27.0 - 05-29-2020
-
-- Add renderRaw method to set render value as is.
-
-### v4.26.1 - 05-29-2020
-
-- Fix array listing and allow customer separator.
-
-### v4.26.0 - 05-29-2020
-
-- Add support for comma separated list from an array of objects.
-
-### v4.25.1 - 04-17-2020
-
-- Fix PR [#125].
-
-### v4.25.0 - 04-17-2020
-
-- HTML title for columns labels [#125], credits to @mgralikowski.
-
-### v4.24.0 - 04-02-2020
-
-- Add TextArea rows & cols fluent attribute setter.
-
-### v4.23.1 - 03-04-2020
-
-- Improve addClass method. [#117], credits to @matteocostantini.
-
-### v4.23.0 - 03-04-2020
-
-- Allow Laravel 7 [#124], credits to @barryvdh.
-
-### v4.22.0 - 03-03-2020
-
-- Add shortcut method `hidden` to hide column instead of `visible(false)`.
-
-### v4.21.1 - 02-21-2020
-
-- Use full url on ajax if not set. [#122]
-- Fix [yajra/laravel-datatables#2322](https://github.com/yajra/laravel-datatables/issues/2322).
-- Fix [#121]
-
-### v4.21.0 - 02-18-2020
-
-- Add editor button formMessage and formTitle fluent setter.
-
-### v4.20.2 - 02-17-2020
-
-- Fix export function not working when base url is set on header.
-
-### v4.20.1 - 11-11-2019
-
-- Fix substring to substr [#116].
-
-### v4.20.0 - 11-11-2019
-
-- Improve adding custom action to buttons. [#114], credits to @om3rcitak.
-
-### v4.19.4 - 10-02-2019
-
-- Fix serialization of renderJs parameters. [#110]
-- Allow array parameter on buttons option for api consistency. [#111]
-- Allow array parameter on editors option for api consistency. [#112]
-
-### v4.19.3 - 09-27-2019
-
-- Fix Button class doc return type to static.
-
-### v4.19.2 - 09-27-2019
-
-- Fix authorization options to allow null.
-
-### v4.19.1 - 09-27-2019
-
-- Fix missing button name attr setter.
-
-### v4.19.0 - 09-25-2019
-
-- Add Editor formOptions setter as per docs: https://editor.datatables.net/reference/option/formOptions.
-
-### v4.18.2 - 09-25-2019
-
-- Fix ajax data if value is an array.
-
-### v4.18.1 - 09-25-2019
-
-- Add ajax url setter.
-- Fix ajax option if array was passed.
-
-### v4.18.0 - 09-23-2019
-
-- Add makeIfCannot authorization.
-
-```php
-Field\Text::makeIfCannot('evaluate', 'evaluator_id')->data('evaluator.name')...
-```
-
-### v4.17.0 - 09-23-2019
-
-- Add support for Field class authorizations.
-- Fix doc blocks and phpstorm warnings.
-
-```php
-Field\Select::makeIfCan('evaluate', 'evaluator_id')...
-Field\Select::makeIf(true, 'evaluator_id')...
-Field\Select::makeIf(function() { return true; }, 'evaluator_id')...
-```
-
-### v4.16.0 - 09-20-2019
-
-- Add action script helpers.
-- New actions: `actionSubmit(), actionClose(), actionHandler('editor-method-handler')`
-
-```php
-Button::make('edit')
- ->editor('evaluator')
- ->text(' Evaluate')
- ->formButtons([
- Button::raw('Approve')
- ->className('btn btn-success ml-2')
- ->actionHandler('approve'),
- Button::raw('Decline')
- ->className('btn btn-danger ml-2')
- ->actionHandler('decline'),
- Button::raw('Cancel')
- ->className('btn btn-secondary ml-2')
- ->actionClose(),
- ])
- ->className('btn-success'),
-```
-
-- Add missing formButtons and action setter.
-- Add raw buttons factory.
-
-```php
-Button::make('edit')
- ->editor('approver')
- ->text(' Approve Leave')
- ->formButtons([
- Button::raw('Approve')
- ->className('btn btn-success')
- ->action('function() { this.submit(); }'),
- Button::raw('Cancel')
- ->className('btn btn-secondary ml-2')
- ->action('function() { this.close(); }'),
- ])
- ->className('btn-success'),
-```
-
-### v4.14.2 - 09-17-2019
-
-- Add missing Button buttons setter.
-
-### v4.14.1 - 09-16-2019
-
-- Fix Number field and set type attr to number.
-- Add missing attr setter.
-- Fix doc blocks for better IDE support.
-
-### v4.14.0 - 09-16-2019
-
-- Add more dateTime opts setter.
-
-### v4.13.0 - 09-14-2019
-
-- Add renderJs ability to pass parameter to js from php argument.
-- `->renderJs('prefix', 'hrs')` == `->renderJs('prefix("hrs")')`
-
-### v4.12.0 - 09-14-2019
-
-- Add renderJs helper to use the built-in and custom renderer.
-- Ex: `->renderJs("boolean()")`, `->renderJs("number()")`.
-
-### v4.11.0 - 09-13-2019
-
-- Add select2 ajax option support. [#109]
-
-### v4.10.1 - 09-10-2019
-
-- Remove editor dependency when display the image.
-- Fix js issue when editing.
-
-### v4.10.0 - 09-10-2019
-
-- Fix displaying of uploaded image preview.
-- Add File editor instance setter.
-
-### v4.9.0 - 09-10-2019
-
-- Add File and Image editor fields. [#108]
-
-### v4.8.0 - 09-04-2019
-
-- Add support Laravel 6.0 & remove deprecated functions [#107], credits to @sangnguyenplus.
-
-### v4.7.1 - 08-31-2019
-
-- Unset editor events key when serializing to array or json.
-- Fix editor events script builder.
-
-### v4.7.0 - 08-29-2019
-
-- Add BelongsTo field builder.
-
-```php
-BelongsTo::model(Model::class, 'name')
-```
-
-### v4.6.0 - 08-29-2019
-
-- Return static on Field for better IDE support.
-- Add initial support for Select2 editor plugin.
-
-### v4.5.4 - 08-22-2019
-
-- Add missing buttons columns & exportOptions setter.
-
-### v4.5.3 - 08-17-2019
-
-- Fix error when no editor fields was defined. [52f0537c5913c84fb5e8a58bbd7db142b987daaf](https://github.com/yajra/laravel-datatables-html/commit/52f0537c5913c84fb5e8a58bbd7db142b987daaf)
-- Return false when validating callback value is an array or an object. [b76cdf806c85368fce70a9034153dec6e107dd2f](https://github.com/yajra/laravel-datatables-html/commit/52f0537c5913c84fb5e8a58bbd7db142b987daaf)
-
-### v4.5.2 - 08-13-2019
-
-- Fix [#102] language key and use i18n. [#103], credits to @matteocostantini.
-
-### v4.5.1 - 07-05-2019
-
-- Add fluent column footer setter. [#101]
-
-### v4.5.0 - 06-27-2019
-
-- Add ability to generate dataTables options for external js use. [#99]
-
-### v4.4.1 - 04-25-2019
-
-- Add title attribute for table headers. [#94], credits to @HOFFMACHINE.
-
-
-### v4.4.0 - 02-27-2019
-
-- Add support for Laravel 5.8 / DataTables v9.0 [#90].
-
-### v4.3.2 - 02-05-2019
-
-- Avoid call parseRender when render attribute is null. [#87] credits to @JulianBustamante.
-
-### v4.3.1 - 11-21-2018
-
-- Allow null string computed column title.
-
-### v4.3.0 - 11-21-2018
-
-#### Added
-
-- Builder Support for the following plugins:
-
-- [x] AutoFill
-- [x] ColReorder
-- [x] FixedColumns
-- [x] FixedHeader
-- [x] KeyTable
-- [x] Responsive
-- [x] RowGroup
-- [x] RowReorder
-- [x] Scroller
-- [x] Select
-
-- Builder Support for setting the language:
-
-- [x] Language
-- [x] Language\Aria
-- [x] Language\AutoFill
-- [x] Language\Paginate
-- [x] Language\Select
-
-- Add missing column option setters:
-
-- [x] data
-- [x] orderData
-- [x] orderDataType
-- [x] orderSequence
-- [x] cellType
-- [x] type
-- [x] contentPadding
-- [x] createdCell
-- [x] editField
-
-### v4.2.1 - 11-21-2018
-
-- Fix computed column title if nothing is set.
-
-### v4.2.0 - 11-20-2018
-
-- Add ajaxWithForm api to process dataTables with form data. [#86]
-
-### v4.1.0 - 11-16-2018
-
-- Add full Editor events script builder as per https://editor.datatables.net/reference/event/.
-
-```php
-Editor::make('create')
- ->on('create', 'js-script-here')
- ->onCreate('js-script-here') // event via magic method.
- ->fields([
- Fields\Text::make('name'),
- Fields\Text::make('email'),
- ]);
-```
-
-- Add missing `idSrc` Editor option setter.
-- Add missing `display` Editor option setter.
-
-> NOTE: You need to force [publish](https://github.com/yajra/laravel-datatables-html#publish-assets-optional) the blade templates to be able to use the features if needed.
-
-### v4.0.0 - 11-14-2018
-
-#### ADDED
-
-Add full builder support for the following options based on https://datatables.net/reference/option/.
-
-##### Add builder support for the following plugins:
-
-- [x] AutoFill
-- [x] Buttons
-- [x] ColReorder
-- [x] FixedColumns
-- [x] FixedHeader
-- [x] KeyTable
-- [x] Responsive
-- [x] RowGroup
-- [x] RowReorder
-- [x] Scroller
-- [x] Select
-
-> Note: All plugins requires their corresponding asset files.
-
-##### Add Buttons builder with support for authorization.
-
-```php
-->buttons(
- Button::makeIfCan('manage-users', 'create')->editor('editor'),
- Button::makeIf(true, 'edit')->editor('editor'),
- Button::make('remove')->editor('editor')->className('btn-danger'),
- Button::make('colvis')->text(''),
- Button::make('export'),
- Button::make('print'),
- Button::make('reset'),
- Button::make('reload')
-)
-```
-
-#### CHANGED
-
-- `Editor` class was moved from `Yajra\DataTables\Html\Editor` to `Yajra\DataTables\Html\Editor\Editor`.
-- All fields were moved from `Yajra\DataTables\Html\Editor` to `Yajra\DataTables\Html\Editor\Fields` namespace.
-
-### v3.13.0 - 11-10-2018
-
-- Add missing visible option setter. [#83]
-- Add new fields, fix dateTime field format. [#84]
-
-#### Changed
-
-- Fix field and column computed title.
-
-From `created_at` with title `Created_At`
-To `created_at` with title `Created At`
-
-#### Fixed
-
-- Fix DateTime field.
-- Set format to `YYYY-MM-DD hh:mm a`.
-- Add `military()` setter to set the time to military format.
-
-#### Added New Fields
-
-- Boolean
-- Date
-- Time
-- Text
-- Number
-
-### v3.12.7 - 11-03-2018
-
-- Add checker if className is not yet set when adding class.
-
-### v3.12.6 - 11-03-2018
-
-- Fix setting of title.
-- Add title option for checkbox column.
-
-### v3.12.5 - 11-03-2018
-
-- Add name arg for computed column.
-
-### v3.12.4 - 11-03-2018
-
-- Fix options: Use 1 and 0 for true or false.
-
-### v3.12.3 - Skipped (My Bad)
-
-### v3.12.2 - 11-03-2018
-
-- Add missing field options setter and add docs link.
-
-### v3.12.1 - 11-03-2018
-
-- Add to method to append a class to the field.
-
-### v3.12.0 - 11-03-2018
-
-- Add editor options collection builder. [#80]
-
-### v3.11.0 - 11-02-2018
-
-- Add option to prepend action column. [#77]
-- Enhance column fluent builder. [#78]
-
-### v3.10.0 - 11-02-2018
-
-- Add support for DataTables Editor script generation. [#73]
-- Fix script template config key `datatables-html.script`.
-- Add method to `getAjaxUrl()`.
-
-### v3.9.0 - 11-02-2018
-
-- Add support for [built-in render helpers](https://datatables.net/manual/data/renderers#Built-in-helpers). [#71], credits to @Razoxane.
-
-### v3.8.1 - 10-30-2018
-
-- Fix the default name of index column to follow DT syntax. [#69], credits to @jaydons.
-- Fix missing periods. [#70], credits to @jaydons.
-
-### v3.8.0 - 09-05-2018
-
-- Add support for Laravel 5.7
-
-### v3.7.2 - 07-06-2018
-
-- Fix callback check on empty values. [#62] Credits to @apreiml.
-
-### v3.7.1 - 03-16-2018
-
-- Add parameter in addCheckbox to prepend or append the checkbox column [#55], credits to @karmendra
-
-### v3.7.0 - 02-21-2018
-
-- Adding ajaxParameters to minifiedAjax [#57], credits to @lk77
-- Fixes the issue with the missing name attribute default mentioned in [#58]. PR [#59], credits to @Namoshek
-
-### v3.6.0 - 02-11-2018
-
-- Add support for Laravel 5.6. [#56]
-
-### v3.5.2 - 01-11-2018
-
-- Moving callback condition to config [#54], credits to @lk77.
-
-### v3.5.1 - 12-27-2017
-
-- Allow jQuery functions callback. [#52], credits to @OzanKurt.
-
-### v3.5.0 - 12-24-2017
-
-- Improve handling of function callbacks and better editor support. [#49]
-
-### v3.4.0 - 12-18-2017
-
-- Implement buttons support for editor. [#47]
-
-### v3.3.0 - 12-15-2017
-
-- Add postAjax() to Html Builder [#45], credits to @ElfSundae.
-- Fix https://github.com/yajra/laravel-datatables-html/pull/13#issuecomment-337947000.
-
-### v3.2.1 - 10-18-2017
-
-- Fix HtmlServiceProvider. [#38], credits to @ElfSundae.
-- Fix changelog PR links. [#39]
-
-### v3.2.0 - 10-13-2017
-
-- Review tableAttributes getter and setter [#31]
-- Fix CS. [#36]
-- Add setTableId() to Html Builder [#35].
-- Add addTableClass, removeTableClass to Html Builder [#37]
-- All changes credits to @ElfSundae.
-
-### v3.1.0 - 09-14-2017
-
-- Added generateJson to Html/Builder [#29], credits to @lk77.
-
-### v3.0.3 - 09-12-2017
-
-- Fix column attributes removed when generate script. [#28], credits to @as247.
-- Fix https://github.com/yajra/laravel-datatables/issues/1380.
-
-### v3.0.2 - 09-09-2017
-
-- Fix Request class doc blocks.
-- Fix typo Datatables to DataTables.
-
-### v3.0.1 - 09-09-2017
-
-- Add fnServerParams to validCallbacks [#26]. Credits to @cracki.
-
-### v3.0.0 - 08-31-2017
-
-- v3.0 stable release.
-
-### v2.0.6 - 07-29-2017
-
-- Adding type GET to minifiedAjax in Html/Builder [#21], credits to @lk77.
-
-### v2.0.5 - 06-29-2017
-
-- Fix fetching of default table id from config. [#19]
-
-### v2.0.4 - 06-29-2017
-
-- Fix missing semi-colon.
-
-### v2.0.3 - 06-29-2017
-
-- Script cleanup [#18]
-- Clean up extra space and floating ; on generated ajax data script.
-- Do not include attributes on generated column scripts.
-
-### v2.0.2 - 06-29-2017
-
-- Fix parsing of column functions. [#17]
-
-### v2.0.1 - 06-29-2017
-
-- Fix parsing of ajax data where function is rendered as string. [#16]
-
-### v2.0.0 - 06-28-2017
-
-- Add support for Laravel 5.5
-- Removed unused classes on constructor.
- - UrlGenerator
- - FormBuilder
-- Fix addCheckbox.
-- Use HtmlString when generating table and scripts markup.
-- Make default table attributes configurable. Fix [#3]
-- Use PHPUNIT 6.x, update tests.
-- Add macroable trait for builder extension via macro calls.
-
-### v1.4.1 - 06-26-2017
-
-- Set default ajax url to empty string.
-
-### v1.4.0 - 06-26-2017
-
-- Add minifiedAjax method to minify url generated when using get request. [#13]
-- Fixes `php artisan serve` and IE issues on long URL.
-- Related Issues:
- yajra/laravel-datatables#1225
- yajra/laravel-datatables#1205
- yajra/laravel-datatables#826
- yajra/laravel-datatables#671
- etc...
-
-### v1.3.0 - 06-24-2017
-
-- Adding addBefore and addColumnBefore in Builder.
-- PR [#12], credits to @lk77.
-
-### v1.2.0 - 03-28-2017
-
-- Add method to remove column by names. [#9]
-
-### v1.1.1 - 03-28-2017
-
-- Fix columns setter. [#8]
+### UNRELEASED
-### v1.1.0 - 02-03-2017
+### v12.0.2 (2025-04-28)
-- Configurable header attributes. [#4]
-- Credits to @alfa6661.
+- fix: use DOMContentLoaded #237
+- fix: https://github.com/yajra/laravel-datatables-html/pull/235
-### v1.0.0 - 01-27-2017
+### v12.0.1 (2025-03-31)
-- First release.
+- feat: select keyboard navigation and selection #236
-[#4]: https://github.com/yajra/laravel-datatables-html/pull/4
-[#8]: https://github.com/yajra/laravel-datatables-html/pull/8
-[#9]: https://github.com/yajra/laravel-datatables-html/pull/9
-[#12]: https://github.com/yajra/laravel-datatables-html/pull/12
-[#13]: https://github.com/yajra/laravel-datatables-html/pull/13
-[#16]: https://github.com/yajra/laravel-datatables-html/pull/16
-[#17]: https://github.com/yajra/laravel-datatables-html/pull/17
-[#18]: https://github.com/yajra/laravel-datatables-html/pull/18
-[#19]: https://github.com/yajra/laravel-datatables-html/pull/19
-[#21]: https://github.com/yajra/laravel-datatables-html/pull/21
-[#26]: https://github.com/yajra/laravel-datatables-html/pull/26
-[#28]: https://github.com/yajra/laravel-datatables-html/pull/28
-[#29]: https://github.com/yajra/laravel-datatables-html/pull/29
-[#31]: https://github.com/yajra/laravel-datatables-html/pull/31
-[#35]: https://github.com/yajra/laravel-datatables-html/pull/35
-[#36]: https://github.com/yajra/laravel-datatables-html/pull/36
-[#37]: https://github.com/yajra/laravel-datatables-html/pull/37
-[#38]: https://github.com/yajra/laravel-datatables-html/pull/38
-[#39]: https://github.com/yajra/laravel-datatables-html/pull/39
-[#47]: https://github.com/yajra/laravel-datatables-html/pull/47
-[#49]: https://github.com/yajra/laravel-datatables-html/pull/49
-[#52]: https://github.com/yajra/laravel-datatables-html/pull/52
-[#54]: https://github.com/yajra/laravel-datatables-html/pull/54
-[#56]: https://github.com/yajra/laravel-datatables-html/pull/56
-[#57]: https://github.com/yajra/laravel-datatables-html/pull/57
-[#59]: https://github.com/yajra/laravel-datatables-html/pull/59
-[#55]: https://github.com/yajra/laravel-datatables-html/pull/55
-[#62]: https://github.com/yajra/laravel-datatables-html/pull/62
-[#69]: https://github.com/yajra/laravel-datatables-html/pull/69
-[#70]: https://github.com/yajra/laravel-datatables-html/pull/70
-[#71]: https://github.com/yajra/laravel-datatables-html/pull/71
-[#73]: https://github.com/yajra/laravel-datatables-html/pull/73
-[#77]: https://github.com/yajra/laravel-datatables-html/pull/77
-[#78]: https://github.com/yajra/laravel-datatables-html/pull/78
-[#80]: https://github.com/yajra/laravel-datatables-html/pull/80
-[#83]: https://github.com/yajra/laravel-datatables-html/pull/83
-[#84]: https://github.com/yajra/laravel-datatables-html/pull/84
-[#86]: https://github.com/yajra/laravel-datatables-html/pull/86
-[#87]: https://github.com/yajra/laravel-datatables-html/pull/87
-[#90]: https://github.com/yajra/laravel-datatables-html/pull/90
-[#94]: https://github.com/yajra/laravel-datatables-html/pull/94
-[#99]: https://github.com/yajra/laravel-datatables-html/pull/99
-[#101]: https://github.com/yajra/laravel-datatables-html/pull/101
-[#103]: https://github.com/yajra/laravel-datatables-html/pull/103
-[#107]: https://github.com/yajra/laravel-datatables-html/pull/107
-[#108]: https://github.com/yajra/laravel-datatables-html/pull/108
-[#109]: https://github.com/yajra/laravel-datatables-html/pull/109
-[#110]: https://github.com/yajra/laravel-datatables-html/pull/110
-[#111]: https://github.com/yajra/laravel-datatables-html/pull/111
-[#112]: https://github.com/yajra/laravel-datatables-html/pull/112
-[#114]: https://github.com/yajra/laravel-datatables-html/pull/114
-[#116]: https://github.com/yajra/laravel-datatables-html/pull/116
-[#122]: https://github.com/yajra/laravel-datatables-html/pull/122
-[#124]: https://github.com/yajra/laravel-datatables-html/pull/124
-[#117]: https://github.com/yajra/laravel-datatables-html/pull/117
-[#125]: https://github.com/yajra/laravel-datatables-html/pull/125
-[#131]: https://github.com/yajra/laravel-datatables-html/pull/131
-[#135]: https://github.com/yajra/laravel-datatables-html/pull/135
-[#127]: https://github.com/yajra/laravel-datatables-html/pull/127
-[#139]: https://github.com/yajra/laravel-datatables-html/pull/139
-[#138]: https://github.com/yajra/laravel-datatables-html/pull/138
-[#133]: https://github.com/yajra/laravel-datatables-html/pull/133
-[#142]: https://github.com/yajra/laravel-datatables-html/pull/142
-[#143]: https://github.com/yajra/laravel-datatables-html/pull/143
-[#144]: https://github.com/yajra/laravel-datatables-html/pull/144
-[#137]: https://github.com/yajra/laravel-datatables-html/pull/137
-[#147]: https://github.com/yajra/laravel-datatables-html/pull/147
-[#152]: https://github.com/yajra/laravel-datatables-html/pull/152
-[#154]: https://github.com/yajra/laravel-datatables-html/pull/154
+### v12.0.0 (2025-02-26)
-[#134]: https://github.com/yajra/laravel-datatables-html/issues/134
-[#3]: https://github.com/yajra/laravel-datatables-html/issues/3
-[#58]: https://github.com/yajra/laravel-datatables-html/issues/58
-[#102]: https://github.com/yajra/laravel-datatables-html/issues/102
-[#121]: https://github.com/yajra/laravel-datatables-html/issues/121
+- feat: Laravel 12 support #234
diff --git a/LICENSE.md b/LICENSE.md
index 7c2696e..178e525 100644
--- a/LICENSE.md
+++ b/LICENSE.md
@@ -1,6 +1,6 @@
(The MIT License)
-Copyright (c) 2013-2018 Arjay Angeles
+Copyright (c) 2013-2022 Arjay Angeles
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
diff --git a/README.md b/README.md
index 2072a3b..9103975 100644
--- a/README.md
+++ b/README.md
@@ -1,29 +1,66 @@
-# Laravel DataTables Html Plugin.
+# Laravel DataTables Html Plugin
-[](http://laravel.com)
+[](http://laravel.com)
[](https://packagist.org/packages/yajra/laravel-datatables-html)
-
[](https://scrutinizer-ci.com/g/yajra/laravel-datatables-html/?branch=master)
[](https://packagist.org/packages/yajra/laravel-datatables-html)
[](https://packagist.org/packages/yajra/laravel-datatables-html)
+[](https://github.com/yajra/laravel-datatables-html/actions/workflows/continuous-integration.yml)
+[](https://github.com/yajra/laravel-datatables-html/actions/workflows/static-analysis.yml)
+[](https://github.com/yajra/laravel-datatables-html/actions/workflows/pint.yml)
+
This package is a plugin of [Laravel DataTables](https://github.com/yajra/laravel-datatables) for generating dataTables script using PHP.
## Requirements
-- [Laravel 5.4+](https://github.com/laravel/framework)
-- [Laravel DataTables v7.x|v8.x|9.x](https://github.com/yajra/laravel-datatables)
+
+- [Laravel 12.x](https://github.com/laravel/framework)
+- [Laravel DataTables](https://github.com/yajra/laravel-datatables)
## Documentations
+
- [Laravel DataTables Documentation](http://yajrabox.com/docs/laravel-datatables)
-- [Demo Application](http://datatables.yajrabox.com) is available for artisan's reference.
+
+## Laravel Version Compatibility
+
+| Laravel | Package |
+|:--------------|:--------|
+| 8.x and below | 4.x |
+| 9.x | 9.x |
+| 10.x | 10.x |
+| 11.x | 11.x |
+| 12.x | 12.x |
## Quick Installation
-`composer require yajra/laravel-datatables-html:^4.0`
-#### Service Provider (Optional on Laravel 5.5+)
-`Yajra\DataTables\HtmlServiceProvider::class`
+`composer require yajra/laravel-datatables-html:^12`
+
+#### Setup scripts with ViteJS
+
+Set the default javascript type to `module` by setting `Builder::useVite()` in the `AppServiceProvider`.
+
+```php
+namespace App\Providers;
+
+use Illuminate\Pagination\Paginator;
+use Illuminate\Support\ServiceProvider;
+use Yajra\DataTables\Html\Builder;
+
+class AppServiceProvider extends ServiceProvider
+{
+ /**
+ * Bootstrap any application services.
+ */
+ public function boot(): void
+ {
+ Paginator::useBootstrapFive();
+ Builder::useVite();
+ }
+}
+```
#### Publish Assets (Optional)
+
`$ php artisan vendor:publish --tag=datatables-html`
And that's it! Start building out some awesome DataTables!
diff --git a/UPGRADE.md b/UPGRADE.md
index 453dc3e..011b035 100644
--- a/UPGRADE.md
+++ b/UPGRADE.md
@@ -1 +1,5 @@
# Upgrade Notes
+
+## v10 to v11
+
+- Editor `scope` method has been renamed to `formScope`.
diff --git a/composer.json b/composer.json
index 81f5b85..784ffcb 100644
--- a/composer.json
+++ b/composer.json
@@ -1,50 +1,68 @@
{
- "name": "yajra/laravel-datatables-html",
- "description": "Laravel DataTables HTML builder plugin for Laravel 5.4+.",
- "keywords": [
- "laravel",
- "dataTables",
- "jquery",
- "html",
- "js"
- ],
- "license": "MIT",
- "authors": [
- {
- "name": "Arjay Angeles",
- "email": "aqangeles@gmail.com"
- }
- ],
- "require": {
- "php": "^7.1.3|^8",
- "ext-json": "*",
- "yajra/laravel-datatables-oracle": "~9.0",
- "laravelcollective/html": "^5.4|^6"
- },
- "require-dev": {
- "mockery/mockery": "^1.3.1",
- "phpunit/phpunit": "^9.3"
- },
- "autoload": {
- "psr-4": {
- "Yajra\\DataTables\\": "src/"
- }
- },
- "autoload-dev": {
- "psr-4": {
- "Yajra\\DataTables\\Tests\\": "tests/"
- }
- },
- "extra": {
- "branch-alias": {
- "dev-master": "4.0-dev"
+ "name": "yajra/laravel-datatables-html",
+ "description": "Laravel DataTables HTML builder plugin",
+ "keywords": [
+ "yajra",
+ "laravel",
+ "dataTables",
+ "jquery",
+ "html",
+ "js"
+ ],
+ "license": "MIT",
+ "authors": [
+ {
+ "name": "Arjay Angeles",
+ "email": "aqangeles@gmail.com"
+ }
+ ],
+ "require": {
+ "php": "^8.2",
+ "ext-json": "*",
+ "yajra/laravel-datatables-oracle": "^12.0"
},
- "laravel": {
- "providers": [
- "Yajra\\DataTables\\HtmlServiceProvider"
- ]
- }
- },
- "minimum-stability": "dev",
- "prefer-stable": true
+ "require-dev": {
+ "larastan/larastan": "^3.1",
+ "orchestra/testbench": "^10",
+ "laravel/pint": "^1.21",
+ "rector/rector": "^2.0",
+ "livewire/livewire": "^3.4"
+ },
+ "suggest": {
+ "laravel/livewire": "Required for Livewire layout support."
+ },
+ "autoload": {
+ "psr-4": {
+ "Yajra\\DataTables\\": "src/"
+ }
+ },
+ "autoload-dev": {
+ "psr-4": {
+ "Yajra\\DataTables\\Html\\Tests\\": "tests/"
+ }
+ },
+ "extra": {
+ "branch-alias": {
+ "dev-master": "12.x-dev"
+ },
+ "laravel": {
+ "providers": [
+ "Yajra\\DataTables\\HtmlServiceProvider"
+ ]
+ }
+ },
+ "scripts": {
+ "test": "./vendor/bin/phpunit",
+ "pint": "./vendor/bin/pint",
+ "rector": "./vendor/bin/rector",
+ "stan": "./vendor/bin/phpstan analyse --memory-limit=2G --ansi --no-progress --no-interaction --configuration=phpstan.neon.dist",
+ "pr": [
+ "@rector",
+ "@pint",
+ "@stan",
+ "@test"
+ ]
+ },
+ "minimum-stability": "dev",
+ "prefer-stable": true
}
diff --git a/phpstan.neon.dist b/phpstan.neon.dist
new file mode 100644
index 0000000..23d24cc
--- /dev/null
+++ b/phpstan.neon.dist
@@ -0,0 +1,20 @@
+includes:
+ - ./vendor/larastan/larastan/extension.neon
+
+parameters:
+
+ paths:
+ - src
+
+ level: 9
+
+ ignoreErrors:
+ - '#Unsafe usage of new static\(\).#'
+ - identifier: missingType.generics
+ - identifier: missingType.iterableValue
+ - identifier: binaryOp.invalid
+ - identifier: return.type
+ - identifier: argument.type
+
+ excludePaths:
+ - ./src/Html/Fluent.php
diff --git a/phpunit.xml b/phpunit.xml
index 3366726..2cb7512 100644
--- a/phpunit.xml
+++ b/phpunit.xml
@@ -1,23 +1,8 @@
-
-
-
- ./tests/
-
-
-
-
- ./vendor
-
-
+
+
+
+ ./tests/
+
+
diff --git a/pint.json b/pint.json
new file mode 100644
index 0000000..93061b6
--- /dev/null
+++ b/pint.json
@@ -0,0 +1,3 @@
+{
+ "preset": "laravel"
+}
diff --git a/rector.php b/rector.php
new file mode 100644
index 0000000..ca7ca05
--- /dev/null
+++ b/rector.php
@@ -0,0 +1,22 @@
+paths([
+ __DIR__.'/src',
+ __DIR__.'/tests',
+ ]);
+
+ // register a single rule
+ $rectorConfig->rule(InlineConstructorDefaultToPropertyRector::class);
+
+ // define sets of rules
+ $rectorConfig->sets([
+ LevelSetList::UP_TO_PHP_82,
+ ]);
+};
diff --git a/src/Html/Builder.php b/src/Html/Builder.php
index 8edd318..9172874 100644
--- a/src/Html/Builder.php
+++ b/src/Html/Builder.php
@@ -2,135 +2,138 @@
namespace Yajra\DataTables\Html;
-use Collective\Html\HtmlBuilder;
use Illuminate\Contracts\Config\Repository;
use Illuminate\Contracts\View\Factory;
-use Illuminate\Support\Arr;
use Illuminate\Support\Collection;
use Illuminate\Support\HtmlString;
-use Illuminate\Support\Str;
use Illuminate\Support\Traits\Macroable;
+use Yajra\DataTables\Utilities\Helper;
class Builder
{
- use Macroable;
- use HasOptions;
- use HasTable;
- use HasEditor;
- use Columns\Index;
use Columns\Action;
use Columns\Checkbox;
+ use Columns\Index;
+ use HasEditor;
+ use HasOptions;
+ use HasTable;
+ use Macroable;
// Select plugin constants.
- const SELECT_STYLE_API = 'api';
- const SELECT_STYLE_SINGLE = 'single';
- const SELECT_STYLE_MULTI = 'multi';
- const SELECT_STYLE_OS = 'os';
- const SELECT_STYLE_MULTI_SHIFT = 'multi+shift';
- const SELECT_ITEMS_ROW = 'row';
- const SELECT_ITEMS_COLUMN = 'column';
- const SELECT_ITEMS_CELL = 'cell';
+ final public const SELECT_STYLE_API = 'api';
- /**
- * @var Collection
- */
- public $collection;
+ final public const SELECT_STYLE_SINGLE = 'single';
- /**
- * @var Repository
- */
- public $config;
+ final public const SELECT_STYLE_MULTI = 'multi';
- /**
- * @var Factory
- */
- public $view;
+ final public const SELECT_STYLE_OS = 'os';
+
+ final public const SELECT_STYLE_MULTI_SHIFT = 'multi+shift';
+
+ final public const SELECT_ITEMS_ROW = 'row';
+
+ final public const SELECT_ITEMS_COLUMN = 'column';
+
+ final public const SELECT_ITEMS_CELL = 'cell';
/**
- * @var HtmlBuilder
+ * The default type to use for the DataTables javascript.
*/
- public $html;
+ protected static string $jsType = 'text/javascript';
/**
- * @var array
+ * @var Collection
*/
- protected $tableAttributes = [];
+ public Collection $collection;
/**
- * @var string
+ * @var array
*/
- protected $template = '';
+ protected array $tableAttributes = [];
+
+ protected string $template = '';
+
+ protected array $attributes = [
+ 'serverSide' => true,
+ 'processing' => true,
+ ];
+
+ protected string|array $ajax = '';
+
+ protected array $additionalScripts = [];
+
+ public function __construct(public Repository $config, public Factory $view, public HtmlBuilder $html)
+ {
+ /** @var array $defaults */
+ $defaults = $this->config->get('datatables-html.table', []);
+
+ $this->collection = new Collection;
+ $this->tableAttributes = $defaults;
+ }
/**
- * @var array
+ * Set the default type to module for the DataTables javascript.
*/
- protected $attributes = [];
+ public static function useVite(): void
+ {
+ static::$jsType = 'module';
+ }
/**
- * @param Repository $config
- * @param Factory $view
- * @param HtmlBuilder $html
+ * Set the default type to text/javascript for the DataTables javascript.
*/
- public function __construct(Repository $config, Factory $view, HtmlBuilder $html)
+ public static function useWebpack(): void
{
- $this->config = $config;
- $this->view = $view;
- $this->html = $html;
- $this->collection = new Collection;
- $this->tableAttributes = $this->config->get('datatables-html.table', []);
- $this->attributes = [
- 'serverSide' => true,
- 'processing' => true,
- ];
+ static::$jsType = 'text/javascript';
}
/**
* Generate DataTable javascript.
- *
- * @param null $script
- * @param array $attributes
- * @return \Illuminate\Support\HtmlString
- * @throws \Exception
*/
- public function scripts($script = null, array $attributes = ['type' => 'text/javascript'])
+ public function scripts(?string $script = null, array $attributes = []): HtmlString
{
$script = $script ?: $this->generateScripts();
- $attributes = $this->html->attributes($attributes);
+ $attributes = $this->html->attributes(
+ array_merge($attributes, ['type' => $attributes['type'] ?? static::$jsType])
+ );
- return new HtmlString("\n");
+ return new HtmlString("");
}
/**
* Get generated raw scripts.
- *
- * @return \Illuminate\Support\HtmlString
- * @throws \Exception
*/
- public function generateScripts()
+ public function generateScripts(): HtmlString
{
$parameters = $this->generateJson();
return new HtmlString(
- sprintf($this->template(), $this->getTableAttribute('id'), $parameters)
+ trim(sprintf($this->template(), $this->getTableAttribute('id'), $parameters))
);
}
/**
* Get generated json configuration.
- *
- * @return string
*/
- public function generateJson()
+ public function generateJson(): string
{
return $this->parameterize($this->getOptions());
}
+ /**
+ * Generate DataTables js parameters.
+ */
+ public function parameterize(array $attributes = []): string
+ {
+ $parameters = (new Parameters($attributes))->toArray();
+
+ return Helper::toJsonScript($parameters);
+ }
+
/**
* Get DataTable options array.
- *
- * @return array
*/
- public function getOptions()
+ public function getOptions(): array
{
return array_merge(
$this->attributes, [
@@ -145,92 +148,42 @@ public function getOptions()
);
}
- /**
- * Generate DataTables js parameters.
- *
- * @param array $attributes
- * @return string
- */
- public function parameterize($attributes = [])
- {
- $parameters = (new Parameters($attributes))->toArray();
-
- $values = [];
- $replacements = [];
-
- foreach (Arr::dot($parameters) as $key => $value) {
- if ($this->isCallbackFunction($value, $key)) {
- $values[] = trim($value);
- Arr::set($parameters, $key, '%' . $key . '%');
- $replacements[] = '"%' . $key . '%"';
- }
- }
-
- $new = [];
- foreach ($parameters as $key => $value) {
- Arr::set($new, $key, $value);
- }
-
- $json = json_encode($new);
-
- $json = str_replace($replacements, $values, $json);
-
- return $json;
- }
-
- /**
- * Check if given key & value is a valid callback js function.
- *
- * @param string $value
- * @param string $key
- * @return bool
- */
- protected function isCallbackFunction($value, $key)
- {
- if (empty($value)) {
- return false;
- }
-
- $callbacks = $this->config->get('datatables-html.callback', ['$', '$.', 'function']);
-
- return Str::startsWith(trim($value), $callbacks) || Str::contains($key, 'editor');
- }
-
/**
* Get javascript template to use.
- *
- * @return string
*/
- protected function template()
+ protected function template(): string
{
- $template = $this->template ?: $this->config->get('datatables-html.script', 'datatables::script');
+ /** @var view-string $configTemplate */
+ $configTemplate = $this->config->get('datatables-html.script', 'datatables::script');
+
+ $template = $this->template ?: $configTemplate;
- return $this->view->make($template, ['editors' => $this->editors])->render();
+ return $this->view->make($template, ['editors' => $this->editors, 'scripts' => $this->additionalScripts])->render();
}
/**
* Generate DataTable's table html.
- *
- * @param array $attributes
- * @param bool $drawFooter
- * @param bool $drawSearch
- * @return \Illuminate\Support\HtmlString
*/
- public function table(array $attributes = [], $drawFooter = false, $drawSearch = false)
+ public function table(array $attributes = [], bool $drawFooter = false, bool $drawSearch = false): HtmlString
{
$this->setTableAttributes($attributes);
$th = $this->compileTableHeaders();
$htmlAttr = $this->html->attributes($this->tableAttributes);
- $tableHtml = '';
- $searchHtml = $drawSearch ? '' . implode('',
- $this->compileTableSearchHeaders()) . '
' : '';
- $tableHtml .= '' . implode('', $th) . '
' . $searchHtml . '';
+ $tableHtml = '';
+ $searchHtml = $drawSearch
+ ? ''.implode('', $this->compileTableSearchHeaders()).'
'
+ : '';
+
+ $tableHtml .= 'theadClass ?? '').'>';
+ $tableHtml .= ''.implode('', $th).'
'.$searchHtml.'';
+
if ($drawFooter) {
$tf = $this->compileTableFooter();
- $tableHtml .= '' . implode('', $tf) . '
';
+ $tableHtml .= ''.implode('', $tf).'
';
}
+
$tableHtml .= '
';
return new HtmlString($tableHtml);
@@ -239,10 +192,9 @@ public function table(array $attributes = [], $drawFooter = false, $drawSearch =
/**
* Configure DataTable's parameters.
*
- * @param array $attributes
* @return $this
*/
- public function parameters(array $attributes = [])
+ public function parameters(array $attributes = []): static
{
$this->attributes = array_merge($this->attributes, $attributes);
@@ -250,52 +202,65 @@ public function parameters(array $attributes = [])
}
/**
- * Set custom javascript template.
+ * Generate scripts that set the dataTables options into a variable.
*
- * @param string $template
* @return $this
*/
- public function setTemplate($template)
+ public function asOptions(): static
{
- $this->template = $template;
-
- return $this;
+ return $this->setTemplate('datatables::options');
}
/**
- * Make a data script to be appended on ajax request of dataTables.
+ * Set custom javascript template.
*
- * @param array $data
- * @return string
+ * @return $this
*/
- protected function makeDataScript(array $data)
+ public function setTemplate(string $template): static
{
- $script = '';
- foreach ($data as $key => $value) {
- $dataValue = $this->isCallbackFunction($value, $key) ? $value : "'{$value}'";
- $script .= PHP_EOL . "data.{$key} = {$dataValue};";
- }
+ $this->template = $template;
- return $script;
+ return $this;
}
/**
- * Generate scripts that sets the dataTables options into a variable.
+ * Wrap dataTable scripts with a function.
*
* @return $this
*/
- public function asOptions()
+ public function asFunction(): static
{
- return $this->setTemplate('datatables::options');
+ return $this->setTemplate('datatables::function');
+ }
+
+ public function getAttributes(): array
+ {
+ return $this->attributes;
+ }
+
+ public function getAttribute(string $key, mixed $default = ''): mixed
+ {
+ return $this->attributes[$key] ?? $default;
+ }
+
+ public function getAjax(?string $key = null): array|string
+ {
+ if (! is_null($key)) {
+ return $this->ajax[$key] ?? '';
+ }
+
+ return $this->ajax;
}
/**
- * Wrap dataTable scripts with a function.
+ * Add additional scripts to the DataTables JS initialization.
*
* @return $this
*/
- public function asFunction()
+ public function addScript(string $view): static
{
- return $this->setTemplate('datatables::function');
+ $this->additionalScripts[] = $view;
+
+ return $this;
}
}
diff --git a/src/Html/Button.php b/src/Html/Button.php
index e63c6a3..0823962 100755
--- a/src/Html/Button.php
+++ b/src/Html/Button.php
@@ -2,20 +2,19 @@
namespace Yajra\DataTables\Html;
-use Illuminate\Support\Fluent;
+use Closure;
use Illuminate\Contracts\Support\Arrayable;
+use Illuminate\Support\Traits\Macroable;
class Button extends Fluent implements Arrayable
{
use HasAuthorizations;
+ use Macroable;
/**
* Make a new button instance.
- *
- * @param string|array $options
- * @return static
*/
- public static function make($options = [])
+ public static function make(array|string $options = []): static
{
if (is_string($options)) {
return new static(['extend' => $options]);
@@ -26,11 +25,8 @@ public static function make($options = [])
/**
* Make a raw button that does not extend anything.
- *
- * @param array $options
- * @return static
*/
- public static function raw($options = [])
+ public static function raw(array|string $options = []): static
{
if (is_string($options)) {
return new static(['text' => $options]);
@@ -42,11 +38,11 @@ public static function raw($options = [])
/**
* Set attr option value.
*
- * @param array $value
* @return $this
+ *
* @see https://datatables.net/reference/option/buttons.buttons.attr
*/
- public function attr(array $value)
+ public function attr(array $value): static
{
$this->attributes['attr'] = $value;
@@ -56,11 +52,11 @@ public function attr(array $value)
/**
* Set available option value.
*
- * @param string $value
* @return $this
+ *
* @see https://datatables.net/reference/option/buttons.buttons.available
*/
- public function available($value)
+ public function available(string $value): static
{
if ($this->isFunction($value)) {
$this->attributes['available'] = $value;
@@ -73,23 +69,20 @@ public function available($value)
/**
* Check if a given value is a function.
- *
- * @param string $value
- * @return bool
*/
- protected function isFunction($value)
+ protected function isFunction(string $value): bool
{
- return substr($value, 0, 8) == 'function';
+ return str_starts_with($value, 'function');
}
/**
* Set enabled option value.
*
- * @param bool $value
* @return $this
+ *
* @see https://datatables.net/reference/option/buttons.buttons.enabled
*/
- public function enabled($value = true)
+ public function enabled(bool $value = true): static
{
$this->attributes['enabled'] = $value;
@@ -99,11 +92,11 @@ public function enabled($value = true)
/**
* Set init option value.
*
- * @param string $value
* @return $this
+ *
* @see https://datatables.net/reference/option/buttons.buttons.init
*/
- public function init($value)
+ public function init(string $value): static
{
if ($this->isFunction($value)) {
$this->attributes['init'] = $value;
@@ -117,11 +110,11 @@ public function init($value)
/**
* Set key option value.
*
- * @param string|array $value
* @return $this
+ *
* @see https://datatables.net/reference/option/buttons.buttons.key
*/
- public function key($value)
+ public function key(array|string $value): static
{
$this->attributes['key'] = $value;
@@ -131,11 +124,11 @@ public function key($value)
/**
* Set extend option value.
*
- * @param string $value
* @return $this
+ *
* @see https://datatables.net/reference/option/buttons.buttons.extend
*/
- public function extend($value)
+ public function extend(string $value): static
{
$this->attributes['extend'] = $value;
@@ -145,11 +138,11 @@ public function extend($value)
/**
* Set editor option value.
*
- * @param string $value
* @return $this
+ *
* @see https://editor.datatables.net/reference/button
*/
- public function editor($value)
+ public function editor(string $value): static
{
$this->attributes['editor'] = $value;
@@ -159,11 +152,11 @@ public function editor($value)
/**
* Set buttons option value.
*
- * @param array $buttons
* @return $this
+ *
* @see https://datatables.net/reference/option/buttons.buttons
*/
- public function buttons(array $buttons)
+ public function buttons(array $buttons): static
{
foreach ($buttons as $key => $button) {
if ($button instanceof Arrayable) {
@@ -177,11 +170,11 @@ public function buttons(array $buttons)
}
/**
- * @param array $buttons
* @return $this
+ *
* @see https://editor.datatables.net/examples/api/cancelButton
*/
- public function formButtons(array $buttons)
+ public function formButtons(array $buttons): static
{
foreach ($buttons as $key => $button) {
if ($button instanceof Arrayable) {
@@ -195,14 +188,14 @@ public function formButtons(array $buttons)
}
/**
- * @param mixed $message
* @return $this
+ *
* @see https://editor.datatables.net/examples/api/removeMessage
* @see https://editor.datatables.net/reference/button/create
* @see https://editor.datatables.net/reference/button/edit
* @see https://editor.datatables.net/reference/button/remove
*/
- public function formMessage($message)
+ public function formMessage(string $message): static
{
$this->attributes['formMessage'] = $message;
@@ -210,13 +203,13 @@ public function formMessage($message)
}
/**
- * @param mixed $title
* @return $this
+ *
* @see https://editor.datatables.net/reference/button/create
* @see https://editor.datatables.net/reference/button/edit
* @see https://editor.datatables.net/reference/button/remove
*/
- public function formTitle($title)
+ public function formTitle(string $title): static
{
$this->attributes['formTitle'] = $title;
@@ -226,11 +219,11 @@ public function formTitle($title)
/**
* Set className option value.
*
- * @param string $value
* @return $this
+ *
* @see https://datatables.net/reference/option/buttons.buttons.className
*/
- public function className($value)
+ public function className(string $value): static
{
$this->attributes['className'] = $value;
@@ -240,11 +233,11 @@ public function className($value)
/**
* Set destroy option value.
*
- * @param string $value
* @return $this
+ *
* @see https://datatables.net/reference/option/buttons.buttons.destroy
*/
- public function destroy($value)
+ public function destroy(string $value): static
{
if ($this->isFunction($value)) {
$this->attributes['destroy'] = $value;
@@ -258,11 +251,11 @@ public function destroy($value)
/**
* Set customize option value.
*
- * @param string $value
* @return $this
+ *
* @see https://datatables.net/reference/button/excelHtml5
*/
- public function customize($value)
+ public function customize(string $value): static
{
$this->attributes['customize'] = $value;
@@ -272,28 +265,29 @@ public function customize($value)
/**
* Append a class name to column.
*
- * @param string $class
* @return $this
*/
- public function addClass($class)
+ public function addClass(string $class): static
{
if (! isset($this->attributes['className'])) {
$this->attributes['className'] = $class;
- } else {
- $this->attributes['className'] .= " $class";
+
+ return $this;
}
+ $this->attributes['className'] = $this->attributes['className']." $class";
+
return $this;
}
/**
* Set text option value.
*
- * @param string $value
* @return $this
+ *
* @see https://datatables.net/reference/option/buttons.buttons.text
*/
- public function text($value)
+ public function text(string $value): static
{
$this->attributes['text'] = $value;
@@ -303,11 +297,11 @@ public function text($value)
/**
* Set titleAttr option value.
*
- * @param string $value
* @return $this
+ *
* @see https://datatables.net/reference/option/buttons.buttons.titleAttr
*/
- public function titleAttr($value)
+ public function titleAttr(string $value): static
{
$this->attributes['titleAttr'] = $value;
@@ -317,11 +311,11 @@ public function titleAttr($value)
/**
* Set name option value.
*
- * @param string $value
* @return $this
+ *
* @see https://datatables.net/reference/option/buttons.buttons.name
*/
- public function name($value)
+ public function name(string $value): static
{
$this->attributes['name'] = $value;
@@ -331,11 +325,11 @@ public function name($value)
/**
* Set namespace option value.
*
- * @param string $value
* @return $this
+ *
* @see https://datatables.net/reference/option/buttons.buttons.namespace
*/
- public function namespace($value)
+ public function namespace(string $value): static
{
$this->attributes['namespace'] = $value;
@@ -345,11 +339,11 @@ public function namespace($value)
/**
* Set tag option value.
*
- * @param string $value
* @return $this
+ *
* @see https://datatables.net/reference/option/buttons.buttons.tag
*/
- public function tag($value)
+ public function tag(string $value): static
{
$this->attributes['tag'] = $value;
@@ -359,10 +353,9 @@ public function tag($value)
/**
* Set columns option value.
*
- * @param mixed $value
* @return $this
*/
- public function columns($value)
+ public function columns(array|string $value): static
{
$this->attributes['columns'] = $value;
@@ -372,10 +365,9 @@ public function columns($value)
/**
* Set exportOptions option value.
*
- * @param mixed $value
* @return $this
*/
- public function exportOptions($value)
+ public function exportOptions(array|string $value): static
{
$this->attributes['exportOptions'] = $value;
@@ -385,24 +377,21 @@ public function exportOptions($value)
/**
* Set action to submit the form.
*
- * @return \Yajra\DataTables\Html\Button
+ * @return $this
*/
- public function actionSubmit()
+ public function actionSubmit(): static
{
- $this->attributes['action'] = 'function() { this.submit(); }';
-
- return $this;
+ return $this->action('function() { this.submit(); }');
}
/**
* Set action option value.
*
- * @param string $value
* @return $this
*/
- public function action($value)
+ public function action(string $value): static
{
- if (substr($value, 0, 8) == 'function') {
+ if (str_starts_with($value, 'function')) {
$this->attributes['action'] = $value;
} else {
$this->attributes['action'] = "function(e, dt, node, config) { $value }";
@@ -414,38 +403,60 @@ public function action($value)
/**
* Set editor class action handler.
*
- * @param string $action
- * @return \Yajra\DataTables\Html\Button
+ * @return $this
*/
- public function actionHandler($action)
+ public function actionHandler(string $action): static
{
- $this->attributes['action'] = "function() { this.submit(null, null, function(data) { data.action = '{$action}'; return data; }) }";
-
- return $this;
+ return $this->action("function() { this.submit(null, null, function(data) { data.action = '{$action}'; return data; }) }");
}
/**
* Set action to close the form.
*
- * @return \Yajra\DataTables\Html\Button
+ * @return $this
*/
- public function actionClose()
+ public function actionClose(): static
{
- $this->attributes['action'] = 'function() { this.close(); }';
-
- return $this;
+ return $this->action('function() { this.close(); }');
}
/**
* Set button alignment.
*
- * @param string $align
- * @return \Yajra\DataTables\Html\Button
+ * @return $this
*/
- public function align($align = 'button-left')
+ public function align(string $align = 'button-left'): static
{
$this->attributes['align'] = $align;
return $this;
}
+
+ /**
+ * Handle dynamic calls to the fluent instance or macroable methods.
+ *
+ * @param string $method
+ * @param array $parameters
+ * @return mixed
+ *
+ * @throws \BadMethodCallException
+ */
+ public function __call($method, $parameters)
+ {
+ // Check if the method is a macro (Macroable functionality).
+ if (static::hasMacro($method)) {
+ $macro = static::$macros[$method];
+
+ if ($macro instanceof Closure) {
+ $macro = $macro->bindTo($this, static::class);
+ }
+
+ return $macro(...$parameters);
+ }
+
+ // Fallback to Fluent behavior if it's not a macro.
+ $this->attributes[$method] = count($parameters) > 0 ? reset($parameters) : true;
+
+ return $this;
+ }
}
diff --git a/src/Html/Column.php b/src/Html/Column.php
index c98ab6b..fcebc04 100644
--- a/src/Html/Column.php
+++ b/src/Html/Column.php
@@ -3,23 +3,38 @@
namespace Yajra\DataTables\Html;
use Illuminate\Support\Arr;
-use Illuminate\Support\Fluent;
use Illuminate\Support\Str;
use Yajra\DataTables\Html\Options\Plugins\SearchPanes;
/**
- * @property string data
- * @property string name
- * @property string orderable
- * @property string searchable
- * @property string printable
- * @property string exportable
- * @property string footer
- * @property array attributes
+ * @property array|string $data
+ * @property string $name
+ * @property string $title
+ * @property string $titleAttr
+ * @property bool $orderable
+ * @property bool $searchable
+ * @property bool $printable
+ * @property bool $exportable
+ * @property array|string $footer
+ * @property array $attributes
+ * @property string $render
+ * @property string $className
+ * @property string $editField
+ * @property int|array $orderData
+ * @property string $orderDataType
+ * @property string $orderSequence
+ * @property string $cellType
+ * @property string $type
+ * @property string $contentPadding
+ * @property string $createdCell
+ * @property string $exportFormat
+ * @property callable $exportRender
+ *
* @see https://datatables.net/reference/option/#columns
*/
class Column extends Fluent
{
+ use HasAuthorizations;
use SearchPanes;
/**
@@ -27,23 +42,23 @@ class Column extends Fluent
*/
public function __construct($attributes = [])
{
- $attributes['title'] = isset($attributes['title']) ? $attributes['title'] : self::titleFormat($attributes['data']);
- $attributes['orderable'] = isset($attributes['orderable']) ? $attributes['orderable'] : true;
- $attributes['searchable'] = isset($attributes['searchable']) ? $attributes['searchable'] : true;
- $attributes['exportable'] = isset($attributes['exportable']) ? $attributes['exportable'] : true;
- $attributes['printable'] = isset($attributes['printable']) ? $attributes['printable'] : true;
- $attributes['footer'] = isset($attributes['footer']) ? $attributes['footer'] : '';
- $attributes['attributes'] = isset($attributes['attributes']) ? $attributes['attributes'] : [];
+ $attributes['title'] ??= self::titleFormat($attributes['data'] ?? '');
+ $attributes['orderable'] ??= true;
+ $attributes['searchable'] ??= true;
+ $attributes['exportable'] ??= true;
+ $attributes['printable'] ??= true;
+ $attributes['footer'] ??= '';
+ $attributes['attributes'] ??= [];
// Allow methods override attribute value
foreach ($attributes as $attribute => $value) {
- $method = 'parse' . ucfirst(strtolower($attribute));
- if (!is_null($value) && method_exists($this, $method)) {
+ $method = 'parse'.ucfirst(strtolower($attribute));
+ if (! is_null($value) && method_exists($this, $method)) {
$attributes[$attribute] = $this->$method($value);
}
}
- if (!isset($attributes['name']) && isset($attributes['data'])) {
+ if (! isset($attributes['name']) && isset($attributes['data'])) {
$attributes['name'] = $attributes['data'];
}
@@ -52,23 +67,30 @@ public function __construct($attributes = [])
/**
* Format string to title case.
+ */
+ public static function titleFormat(string $value): string
+ {
+ return Str::title(str_replace(['.', '_'], ' ', Str::snake($value)));
+ }
+
+ /**
+ * Set column title.
+ *
+ * @return $this
*
- * @param string $value
- * @return string
+ * @see https://datatables.net/reference/option/columns.title
*/
- public static function titleFormat($value)
+ public function title(string $value): static
{
- return Str::title(str_replace('_', ' ', $value));
+ $this->attributes['title'] = $value;
+
+ return $this;
}
/**
* Create a computed column that is not searchable/orderable.
- *
- * @param string $data
- * @param string|null $title
- * @return Column
*/
- public static function computed($data, $title = null)
+ public static function computed(string $data, ?string $title = null): Column
{
if (is_null($title)) {
$title = self::titleFormat($data);
@@ -80,11 +102,11 @@ public static function computed($data, $title = null)
/**
* Set column searchable flag.
*
- * @param bool $flag
* @return $this
+ *
* @see https://datatables.net/reference/option/columns.searchable
*/
- public function searchable(bool $flag = true)
+ public function searchable(bool $flag = true): static
{
$this->attributes['searchable'] = $flag;
@@ -94,61 +116,43 @@ public function searchable(bool $flag = true)
/**
* Set column orderable flag.
*
- * @param bool $flag
* @return $this
+ *
* @see https://datatables.net/reference/option/columns.orderable
*/
- public function orderable(bool $flag = true)
+ public function orderable(bool $flag = true): static
{
$this->attributes['orderable'] = $flag;
return $this;
}
- /**
- * Set column title.
- *
- * @param string $value
- * @return $this
- * @see https://datatables.net/reference/option/columns.title
- */
- public function title($value)
- {
- $this->attributes['title'] = $value;
-
- return $this;
- }
-
/**
* Make a new column instance.
- *
- * @param string $data
- * @param string $name
- * @return Column
*/
- public static function make($data, $name = '')
+ public static function make(array|string $data = [], string $name = ''): static
{
- $attr = [
- 'data' => $data,
- 'name' => $name ?: $data,
- ];
+ $attr = $data;
+ if (is_string($data)) {
+ $attr = [
+ 'data' => $data,
+ 'name' => $name ?: $data,
+ ];
+ }
return new static($attr);
}
/**
* Make a new formatted column instance.
- *
- * @param string $name
- * @return Column
*/
- public static function formatted($name)
+ public static function formatted(string $name): static
{
$attr = [
'data' => $name,
'name' => $name,
'title' => self::titleFormat($name),
- 'render' => 'full.' . $name . '_formatted',
+ 'render' => 'full.'.$name.'_formatted',
];
return new static($attr);
@@ -156,11 +160,8 @@ public static function formatted($name)
/**
* Create a checkbox column.
- *
- * @param string $title
- * @return Column
*/
- public static function checkbox($title = '')
+ public static function checkbox(string $title = ''): static
{
return static::make('')
->content('')
@@ -174,10 +175,9 @@ public static function checkbox($title = '')
/**
* Set column exportable flag.
*
- * @param bool $flag
* @return $this
*/
- public function exportable(bool $flag = true)
+ public function exportable(bool $flag = true): static
{
$this->attributes['exportable'] = $flag;
@@ -187,11 +187,11 @@ public function exportable(bool $flag = true)
/**
* Set column class name.
*
- * @param string $class
* @return $this
+ *
* @see https://datatables.net/reference/option/columns.className
*/
- public function className($class)
+ public function className(string $class): static
{
$this->attributes['className'] = $class;
@@ -201,11 +201,11 @@ public function className($class)
/**
* Set column default content.
*
- * @param string $value
* @return $this
+ *
* @see https://datatables.net/reference/option/columns.defaultContent
*/
- public function content($value)
+ public function content(string $value): static
{
$this->attributes['defaultContent'] = $value;
@@ -215,11 +215,11 @@ public function content($value)
/**
* Set column responsive priority.
*
- * @param int|string $value
* @return $this
+ *
* @see https://datatables.net/reference/option/columns.responsivePriority
*/
- public function responsivePriority($value)
+ public function responsivePriority(int|string $value): static
{
$this->attributes['responsivePriority'] = $value;
@@ -230,9 +230,10 @@ public function responsivePriority($value)
* Set column hidden state.
*
* @return $this
+ *
* @see https://datatables.net/reference/option/columns.visible
*/
- public function hidden()
+ public function hidden(): static
{
return $this->visible(false);
}
@@ -240,11 +241,11 @@ public function hidden()
/**
* Set column visible flag.
*
- * @param bool $flag
* @return $this
+ *
* @see https://datatables.net/reference/option/columns.visible
*/
- public function visible(bool $flag = true)
+ public function visible(bool $flag = true): static
{
$this->attributes['visible'] = $flag;
@@ -254,12 +255,11 @@ public function visible(bool $flag = true)
/**
* Append a class name to field.
*
- * @param string $class
* @return $this
*/
- public function addClass($class)
+ public function addClass(string $class): static
{
- if (!isset($this->attributes['className'])) {
+ if (! isset($this->attributes['className'])) {
$this->attributes['className'] = $class;
} else {
$this->attributes['className'] .= " $class";
@@ -271,10 +271,9 @@ public function addClass($class)
/**
* Set column printable flag.
*
- * @param bool $flag
* @return $this
*/
- public function printable(bool $flag = true)
+ public function printable(bool $flag = true): static
{
$this->attributes['printable'] = $flag;
@@ -284,11 +283,11 @@ public function printable(bool $flag = true)
/**
* Set column width value.
*
- * @param int|string $value
* @return $this
+ *
* @see https://datatables.net/reference/option/columns.width
*/
- public function width($value)
+ public function width(int|string $value): static
{
$this->attributes['width'] = $value;
@@ -298,11 +297,12 @@ public function width($value)
/**
* Set column data option value.
*
- * @param string $value
* @return $this
+ *
* @see https://datatables.net/reference/option/columns.data
+ * @see https://datatables.net/manual/data/orthogonal-data
*/
- public function data($value)
+ public function data(array|string $value): static
{
$this->attributes['data'] = $value;
@@ -312,11 +312,11 @@ public function data($value)
/**
* Set column name option value.
*
- * @param string $value
* @return $this
+ *
* @see https://datatables.net/reference/option/columns.name
*/
- public function name($value)
+ public function name(string $value): static
{
$this->attributes['name'] = $value;
@@ -326,11 +326,11 @@ public function name($value)
/**
* Set column edit field option value.
*
- * @param string|array $value
* @return $this
+ *
* @see https://datatables.net/reference/option/columns.editField
*/
- public function editField($value)
+ public function editField(array|string $value): static
{
$this->attributes['editField'] = $value;
@@ -340,11 +340,11 @@ public function editField($value)
/**
* Set column orderData option value.
*
- * @param mixed $value
* @return $this
+ *
* @see https://datatables.net/reference/option/columns.orderData
*/
- public function orderData($value)
+ public function orderData(array|int $value): static
{
$this->attributes['orderData'] = $value;
@@ -354,11 +354,11 @@ public function orderData($value)
/**
* Set column orderDataType option value.
*
- * @param mixed $value
* @return $this
+ *
* @see https://datatables.net/reference/option/columns.orderDataType
*/
- public function orderDataType($value)
+ public function orderDataType(string $value): static
{
$this->attributes['orderDataType'] = $value;
@@ -368,11 +368,11 @@ public function orderDataType($value)
/**
* Set column orderSequence option value.
*
- * @param mixed $value
* @return $this
+ *
* @see https://datatables.net/reference/option/columns.orderSequence
*/
- public function orderSequence($value)
+ public function orderSequence(array $value): static
{
$this->attributes['orderSequence'] = $value;
@@ -382,11 +382,11 @@ public function orderSequence($value)
/**
* Set column cellType option value.
*
- * @param mixed $value
* @return $this
+ *
* @see https://datatables.net/reference/option/columns.cellType
*/
- public function cellType($value)
+ public function cellType(string $value = 'th'): static
{
$this->attributes['cellType'] = $value;
@@ -396,11 +396,11 @@ public function cellType($value)
/**
* Set column type option value.
*
- * @param mixed $value
* @return $this
+ *
* @see https://datatables.net/reference/option/columns.type
*/
- public function type($value)
+ public function type(string $value): static
{
$this->attributes['type'] = $value;
@@ -410,11 +410,11 @@ public function type($value)
/**
* Set column contentPadding option value.
*
- * @param mixed $value
* @return $this
+ *
* @see https://datatables.net/reference/option/columns.contentPadding
*/
- public function contentPadding($value)
+ public function contentPadding(string $value): static
{
$this->attributes['contentPadding'] = $value;
@@ -424,11 +424,11 @@ public function contentPadding($value)
/**
* Set column createdCell option value.
*
- * @param mixed $value
* @return $this
+ *
* @see https://datatables.net/reference/option/columns.createdCell
*/
- public function createdCell($value)
+ public function createdCell(string $value): static
{
$this->attributes['createdCell'] = $value;
@@ -438,23 +438,23 @@ public function createdCell($value)
/**
* Use the js renderer "$.fn.dataTable.render.".
*
- * @param mixed $value
- * @param mixed ...$params
+ * @param int|string|null ...$params
* @return $this
+ *
* @see https://datatables.net/reference/option/columns.render
*/
- public function renderJs($value, ...$params)
+ public function renderJs(string $value, ...$params): static
{
if ($params) {
$value .= '(';
foreach ($params as $param) {
- $value .= "'{$param}',";
+ $value .= sprintf("'%s',", $param);
}
$value = mb_substr($value, 0, -1);
$value .= ')';
}
- $renderer = '$.fn.dataTable.render.' . $value;
+ $renderer = '$.fn.dataTable.render.'.$value;
return $this->render($renderer);
}
@@ -462,11 +462,11 @@ public function renderJs($value, ...$params)
/**
* Set column renderer.
*
- * @param mixed $value
* @return $this
+ *
* @see https://datatables.net/reference/option/columns.render
*/
- public function render($value)
+ public function render(mixed $value): static
{
$this->attributes['render'] = $this->parseRender($value);
@@ -474,12 +474,21 @@ public function render($value)
}
/**
- * Parse render attribute.
+ * Set Callback function to render column for Print + Export
*
- * @param mixed $value
- * @return string|null
+ * @return $this
+ */
+ public function exportRender(callable $callback): static
+ {
+ $this->attributes['exportRender'] = $callback;
+
+ return $this;
+ }
+
+ /**
+ * Parse render attribute.
*/
- public function parseRender($value)
+ public function parseRender(mixed $value): ?string
{
/** @var \Illuminate\Contracts\View\Factory $view */
$view = app('view');
@@ -494,7 +503,7 @@ public function parseRender($value)
return $value($parameters);
} elseif ($this->isBuiltInRenderFunction($value)) {
return $value;
- } elseif ($view->exists($value)) {
+ } elseif (is_string($value) && strlen($value) < 256 && $view->exists($value)) {
return $view->make($value)->with($parameters)->render();
}
@@ -503,11 +512,8 @@ public function parseRender($value)
/**
* Check if given key & value is a valid datatables built-in renderer function.
- *
- * @param string $value
- * @return bool
*/
- private function isBuiltInRenderFunction($value)
+ private function isBuiltInRenderFunction(string $value): bool
{
if (empty($value)) {
return false;
@@ -518,11 +524,8 @@ private function isBuiltInRenderFunction($value)
/**
* Display render value as is.
- *
- * @param mixed $value
- * @return string
*/
- private function parseRenderAsString($value)
+ private function parseRenderAsString(string $value): string
{
return "function(data,type,full,meta){return $value;}";
}
@@ -530,11 +533,11 @@ private function parseRenderAsString($value)
/**
* Set column renderer with give raw value.
*
- * @param mixed $value
* @return $this
+ *
* @see https://datatables.net/reference/option/columns.render
*/
- public function renderRaw($value)
+ public function renderRaw(mixed $value): static
{
$this->attributes['render'] = $value;
@@ -544,10 +547,9 @@ public function renderRaw($value)
/**
* Set column footer.
*
- * @param mixed $value
* @return $this
*/
- public function footer($value)
+ public function footer(mixed $value): static
{
$this->attributes['footer'] = $value;
@@ -555,12 +557,11 @@ public function footer($value)
}
/**
- * Set custom html title instead defult label.
+ * Set custom html title instead default label.
*
- * @param mixed $value
* @return $this
*/
- public function titleAttr($value)
+ public function titleAttr(mixed $value): static
{
$this->attributes['titleAttr'] = $value;
@@ -570,22 +571,23 @@ public function titleAttr($value)
/**
* Set excel column format when exporting.
*
- * @param string $format
* @return $this
+ *
* @see https://github.com/yajra/laravel-datatables-export
*/
- public function exportFormat($format)
+ public function exportFormat(string|callable $format): static
{
$this->attributes['exportFormat'] = $format;
return $this;
}
- /**
- * @return array
- */
- public function toArray()
+ public function toArray(): array
{
+ if (! $this->isAuthorized()) {
+ return [];
+ }
+
return Arr::except($this->attributes, [
'printable',
'exportable',
diff --git a/src/Html/ColumnDefinition.php b/src/Html/ColumnDefinition.php
index 4a4fba9..a05cf29 100644
--- a/src/Html/ColumnDefinition.php
+++ b/src/Html/ColumnDefinition.php
@@ -2,16 +2,51 @@
namespace Yajra\DataTables\Html;
-use Illuminate\Support\Fluent;
-
-class ColumnDefinition extends Fluent
+/**
+ * @see https://datatables.net/reference/option/columnDefs
+ */
+class ColumnDefinition extends Column
{
- use HasOptions;
+ /**
+ * @param array $attributes
+ */
+ public function __construct($attributes = [])
+ {
+ parent::__construct($attributes);
+
+ $this->attributes = $attributes;
+ }
+
+ /**
+ * @return $this
+ *
+ * @see https://datatables.net/reference/option/columnDefs.targets
+ */
+ public function targets(array|string|int $value): static
+ {
+ $this->attributes['targets'] = $value;
+
+ return $this;
+ }
- public function targets($value)
+ /**
+ * @return $this
+ *
+ * @see https://datatables.net/reference/option/columns
+ */
+ public function columns(array $value): static
{
- $this->attributes['targets'] = (array) $value;
+ $this->attributes['columns'] = $value;
return $this;
}
+
+ public function toArray(): array
+ {
+ $array = parent::toArray();
+
+ unset($array['attributes']);
+
+ return $array;
+ }
}
diff --git a/src/Html/ColumnDefinitions.php b/src/Html/ColumnDefinitions.php
index 83816de..2e213e3 100644
--- a/src/Html/ColumnDefinitions.php
+++ b/src/Html/ColumnDefinitions.php
@@ -4,7 +4,4 @@
use Illuminate\Support\Collection;
-class ColumnDefinitions extends Collection
-{
-
-}
+class ColumnDefinitions extends Collection {}
diff --git a/src/Html/Columns/Action.php b/src/Html/Columns/Action.php
index 2e6d7b3..d18be02 100644
--- a/src/Html/Columns/Action.php
+++ b/src/Html/Columns/Action.php
@@ -7,13 +7,11 @@
trait Action
{
/**
- * Add a action column.
+ * Add an action column.
*
- * @param array $attributes
- * @param bool $prepend
* @return $this
*/
- public function addAction(array $attributes = [], $prepend = false)
+ public function addAction(array $attributes = [], bool $prepend = false): static
{
$attributes = array_merge([
'defaultContent' => '',
diff --git a/src/Html/Columns/Checkbox.php b/src/Html/Columns/Checkbox.php
index 3816a2b..dc29677 100644
--- a/src/Html/Columns/Checkbox.php
+++ b/src/Html/Columns/Checkbox.php
@@ -9,15 +9,14 @@ trait Checkbox
/**
* Add a checkbox column.
*
- * @param array $attributes
- * @param bool|int $position true to prepend, false to append or a zero-based index for positioning
+ * @param bool|int $position true to prepend, false to append or a zero-based index for positioning
* @return $this
*/
- public function addCheckbox(array $attributes = [], $position = false)
+ public function addCheckbox(array $attributes = [], bool|int $position = false): static
{
$attributes = array_merge([
- 'defaultContent' => 'html->attributes($attributes) . '/>',
- 'title' => 'html->attributes($attributes + ['id' => 'dataTablesCheckbox']) . '/>',
+ 'defaultContent' => 'html->attributes($attributes).'/>',
+ 'title' => 'html->attributes($attributes + ['id' => 'dataTablesCheckbox']).'/>',
'data' => 'checkbox',
'name' => 'checkbox',
'orderable' => false,
diff --git a/src/Html/Columns/Index.php b/src/Html/Columns/Index.php
index 9672653..3bdfa6c 100644
--- a/src/Html/Columns/Index.php
+++ b/src/Html/Columns/Index.php
@@ -9,10 +9,9 @@ trait Index
/**
* Add a index column.
*
- * @param array $attributes
* @return $this
*/
- public function addIndex(array $attributes = [])
+ public function addIndex(array $attributes = []): static
{
$indexColumn = $this->config->get('datatables.index_column', 'DT_RowIndex');
diff --git a/src/Html/Editor/Editor.php b/src/Html/Editor/Editor.php
index d6617af..4e9b4b8 100644
--- a/src/Html/Editor/Editor.php
+++ b/src/Html/Editor/Editor.php
@@ -4,29 +4,50 @@
use Illuminate\Support\Arr;
use Illuminate\Support\Str;
-use Illuminate\Support\Fluent;
+use Illuminate\Support\Traits\Macroable;
+use Yajra\DataTables\Html\Editor\Fields\Field;
+use Yajra\DataTables\Html\Fluent;
use Yajra\DataTables\Html\HasAuthorizations;
use Yajra\DataTables\Utilities\Helper;
-use Yajra\DataTables\Html\Editor\Fields\Field;
+/**
+ * @property string $instance
+ * @property string|null $table
+ * @property string|array|null $ajax
+ * @property array $fields
+ * @property string|null $template
+ * @property string $idSrc
+ * @property string $display
+ * @property string $scripts
+ * @property array $formOptions
+ */
class Editor extends Fluent
{
- use HasEvents;
use HasAuthorizations;
+ use HasEvents, Macroable {
+ Macroable::__call as macroCall;
+ }
+
+ final public const DISPLAY_LIGHTBOX = 'lightbox';
+
+ final public const DISPLAY_ENVELOPE = 'envelope';
- const DISPLAY_LIGHTBOX = 'lightbox';
- const DISPLAY_ENVELOPE = 'envelope';
- const DISPLAY_BOOTSTRAP = 'bootstrap';
- const DISPLAY_FOUNDATION = 'foundation';
- const DISPLAY_JQUERYUI = 'jqueryui';
+ final public const DISPLAY_BOOTSTRAP = 'bootstrap';
+
+ final public const DISPLAY_FOUNDATION = 'foundation';
+
+ final public const DISPLAY_JQUERYUI = 'jqueryui';
+
+ public array $events = [];
/**
* Editor constructor.
*
- * @param string|array $instance
+ * @param string|array $instance
*/
public function __construct($instance = 'editor')
{
+ $attributes = [];
$attributes['instance'] = $instance;
parent::__construct($attributes);
@@ -34,11 +55,8 @@ public function __construct($instance = 'editor')
/**
* Make new Editor instance.
- *
- * @param string $instance
- * @return Editor
*/
- public static function make($instance = 'editor')
+ public static function make(array|string $instance = 'editor'): static
{
if (is_array($instance)) {
$instance = $instance['editor'] ?? 'editor';
@@ -50,10 +68,9 @@ public static function make($instance = 'editor')
/**
* Append raw scripts.
*
- * @param string $scripts
- * @return Editor
+ * @return $this
*/
- public function scripts($scripts)
+ public function scripts(string $scripts): static
{
$this->attributes['scripts'] = $scripts;
@@ -63,10 +80,9 @@ public function scripts($scripts)
/**
* Set Editor's variable name / instance.
*
- * @param $instance
* @return $this
*/
- public function instance($instance)
+ public function instance(string $instance): static
{
$this->attributes['instance'] = $instance;
@@ -76,11 +92,11 @@ public function instance($instance)
/**
* Set Editor's ajax parameter.
*
- * @param string|array $ajax
* @return $this
+ *
* @see https://editor.datatables.net/reference/option/ajax
*/
- public function ajax($ajax)
+ public function ajax(array|string $ajax): static
{
$this->attributes['ajax'] = $ajax;
@@ -90,11 +106,11 @@ public function ajax($ajax)
/**
* Set Editor's table source.
*
- * @param string $table
* @return $this
+ *
* @see https://editor.datatables.net/reference/option/table
*/
- public function table($table)
+ public function table(string $table): static
{
$this->attributes['table'] = $table;
@@ -104,11 +120,11 @@ public function table($table)
/**
* Set Editor's idSrc option.
*
- * @param string $idSrc
* @return $this
+ *
* @see https://editor.datatables.net/reference/option/idSrc
*/
- public function idSrc($idSrc = 'DT_RowId')
+ public function idSrc(string $idSrc = 'DT_RowId'): static
{
$this->attributes['idSrc'] = $idSrc;
@@ -118,11 +134,11 @@ public function idSrc($idSrc = 'DT_RowId')
/**
* Set Editor's display option.
*
- * @param string $display
* @return $this
+ *
* @see https://editor.datatables.net/reference/option/display
*/
- public function display($display)
+ public function display(string $display): static
{
$this->attributes['display'] = $display;
@@ -132,11 +148,11 @@ public function display($display)
/**
* Set Editor's fields.
*
- * @param array $fields
* @return $this
+ *
* @see https://editor.datatables.net/reference/option/fields
*/
- public function fields(array $fields)
+ public function fields(array $fields): static
{
$this->attributes['fields'] = $fields;
@@ -144,30 +160,28 @@ public function fields(array $fields)
}
/**
- * Set Editor's formOptions.
+ * Set Editor's bubble formOptions.
*
- * @param mixed $formOptions
* @return $this
- * @see https://editor.datatables.net/reference/option/formOptions
- * @see https://editor.datatables.net/reference/type/form-options
+ *
+ * @see https://editor.datatables.net/reference/option/formOptions.bubble
*/
- public function formOptions(array $formOptions)
+ public function formOptionsBubble(array|FormOptions $formOptions): static
{
- $this->attributes['formOptions'] = $formOptions;
-
- return $this;
+ return $this->formOptions(['bubble' => Helper::castToArray($formOptions)]);
}
/**
- * Set Editor's bubble formOptions.
+ * Set Editor's formOptions.
*
- * @param mixed $formOptions
* @return $this
- * @see https://editor.datatables.net/reference/option/formOptions.bubble
+ *
+ * @see https://editor.datatables.net/reference/option/formOptions
+ * @see https://editor.datatables.net/reference/type/form-options
*/
- public function formOptionsBubble(array $formOptions)
+ public function formOptions(array $formOptions): static
{
- $this->attributes['formOptions']['bubble'] = Helper::castToArray($formOptions);;
+ $this->attributes['formOptions'] = $formOptions;
return $this;
}
@@ -175,39 +189,35 @@ public function formOptionsBubble(array $formOptions)
/**
* Set Editor's inline formOptions.
*
- * @param mixed $formOptions
* @return $this
+ *
* @see https://editor.datatables.net/reference/option/formOptions.inline
*/
- public function formOptionsInline($formOptions)
+ public function formOptionsInline(array|FormOptions $formOptions): static
{
- $this->attributes['formOptions']['inline'] = Helper::castToArray($formOptions);
-
- return $this;
+ return $this->formOptions(['inline' => Helper::castToArray($formOptions)]);
}
/**
* Set Editor's main formOptions.
*
- * @param mixed $formOptions
* @return $this
+ *
* @see https://editor.datatables.net/reference/option/formOptions.main
*/
- public function formOptionsMain($formOptions)
+ public function formOptionsMain(array|FormOptions $formOptions): static
{
- $this->attributes['formOptions']['main'] = Helper::castToArray($formOptions);
-
- return $this;
+ return $this->formOptions(['main' => Helper::castToArray($formOptions)]);
}
/**
* Set Editor's language.
*
- * @param array $language
* @return $this
+ *
* @see https://editor.datatables.net/reference/option/i18n
*/
- public function language(array $language)
+ public function language(array $language): static
{
$this->attributes['i18n'] = $language;
@@ -217,11 +227,11 @@ public function language(array $language)
/**
* Set Editor's template.
*
- * @param string $template
* @return $this
+ *
* @see https://editor.datatables.net/reference/option/template
*/
- public function template($template)
+ public function template(string $template): static
{
$this->attributes['template'] = $template;
@@ -230,16 +240,18 @@ public function template($template)
/**
* Convert the fluent instance to an array.
- *
- * @return array
*/
- public function toArray()
+ public function toArray(): array
{
+ if (! $this->isAuthorized()) {
+ return [];
+ }
+
$array = parent::toArray();
unset($array['events']);
- foreach (Arr::get($array, 'fields', []) as $key => &$field) {
+ foreach ((array) Arr::get($array, 'fields', []) as $key => &$field) {
if ($field instanceof Field) {
Arr::set($array['fields'], $key, $field->toArray());
}
@@ -251,53 +263,76 @@ public function toArray()
/**
* Convert the fluent instance to JSON.
*
- * @param int $options
- * @return string
+ * @param int $options
*/
- public function toJson($options = 0)
+ public function toJson($options = 0): string
{
$parameters = $this->jsonSerialize();
unset($parameters['events']);
- $values = [];
- $replacements = [];
+ return Helper::toJsonScript($parameters, $options);
+ }
- foreach (Arr::dot($parameters) as $key => $value) {
- if ($this->isCallbackFunction($value, $key)) {
- $values[] = trim($value);
- Arr::set($parameters, $key, '%' . $key . '%');
- $replacements[] = '"%' . $key . '%"';
- }
- }
+ /**
+ * Hide fields on create action.
+ *
+ * @return $this
+ */
+ public function hiddenOnCreate(array $fields): static
+ {
+ return $this->hiddenOn('create', $fields);
+ }
- $new = [];
- foreach ($parameters as $key => $value) {
- Arr::set($new, $key, $value);
+ /**
+ * Hide fields on specific action.
+ *
+ * @return $this
+ */
+ public function hiddenOn(string $action, array $fields): static
+ {
+ $script = 'function(e, mode, action) {';
+ $script .= "if (action === '$action') {";
+ foreach ($fields as $field) {
+ $script .= "this.hide('$field');";
}
+ $script .= '} else {';
+ foreach ($fields as $field) {
+ $script .= "this.show('$field');";
+ }
+ $script .= '}';
+ $script .= 'return true;';
+ $script .= '}';
- $json = json_encode($new, $options);
-
- $json = str_replace($replacements, $values, $json);
+ $this->onPreOpen($script);
- return $json;
+ return $this;
}
/**
- * Check if given key & value is a valid callback js function.
+ * Hide fields on edit action.
*
- * @param string $value
- * @param string $key
- * @return bool
+ * @return $this
*/
- protected function isCallbackFunction($value, $key)
+ public function hiddenOnEdit(array $fields): static
+ {
+ return $this->hiddenOn('edit', $fields);
+ }
+
+ public function __call($method, $parameters): static
{
- if (empty($value) || is_object($value) || is_array($value)) {
- return false;
+ if (Str::startsWith($method, 'on')) {
+ $event = Str::camel(substr($method, 2, strlen($method) - 2));
+
+ return $this->on($event, $parameters[0]);
}
- $callbacks = config('datatables-html.callback', ['$', '$.', 'function']);
+ $macroCall = $this->macroCall($method, $parameters);
+
+ if (! $macroCall instanceof Editor) {
+ abort(500, sprintf('Method %s::%s must return an Editor instance.', static::class, $method));
+ }
- return Str::startsWith(trim($value), $callbacks) || Str::contains($key, ['editor', 'minDate', 'maxDate']);
+ return $this;
}
}
diff --git a/src/Html/Editor/Fields/BelongsTo.php b/src/Html/Editor/Fields/BelongsTo.php
index b09a29d..2bc8fe6 100644
--- a/src/Html/Editor/Fields/BelongsTo.php
+++ b/src/Html/Editor/Fields/BelongsTo.php
@@ -2,54 +2,26 @@
namespace Yajra\DataTables\Html\Editor\Fields;
-use Illuminate\Support\Str;
use Illuminate\Database\Eloquent\Builder;
+use Illuminate\Support\Str;
class BelongsTo extends Select
{
/**
- * @param string|Builder $class
- * @param string $text
- * @param string $id
- * @param string|null $foreign
- * @return \Yajra\DataTables\Html\Editor\Fields\Field|static
+ * @param class-string<\Illuminate\Database\Eloquent\Model>|Builder $class
*/
- public static function model($class, $text, $id = 'id', $foreign = null)
+ public static function model(Builder|string $class, string $text, string $id = 'id', ?string $foreign = null): static
{
if ($class instanceof Builder) {
$table = $class->getModel()->getTable();
} else {
- $table = app($class)->getTable();
+ $table = (new $class)->getTable();
}
- $table = Str::singular($table);
- $foreign = $foreign ?? $table . '_id';
+ $table = Str::singular($table);
+ $foreign ??= $table.'_id';
return self::make($foreign, Str::title($table))
- ->modelOptions($class, $text, $id);
- }
-
- /**
- * Add a placeholder and allow clear.
- * Note: This requires editor select2 plugin.
- *
- * @see https://editor.datatables.net/plug-ins/field-type/editor.select2
- * @param string $text
- * @param null|string $id
- * @param bool $allowClear
- * @return $this
- */
- public function placeholder($text, $id = null, $allowClear = true)
- {
- $this->type('select2')
- ->opts([
- 'allowClear' => $allowClear,
- 'placeholder' => [
- 'id' => $id,
- 'text' => $text,
- ],
- ]);
-
- return $this;
+ ->modelOptions($class, $text, $id);
}
}
diff --git a/src/Html/Editor/Fields/Boolean.php b/src/Html/Editor/Fields/Boolean.php
index 86e8e49..9259d24 100644
--- a/src/Html/Editor/Fields/Boolean.php
+++ b/src/Html/Editor/Fields/Boolean.php
@@ -6,12 +6,8 @@ class Boolean extends Checkbox
{
/**
* Make a new instance of a field.
- *
- * @param string $name
- * @param string $label
- * @return static|\Yajra\DataTables\Html\Editor\Fields\Field
*/
- public static function make($name, $label = '')
+ public static function make(array|string $name, string $label = ''): static
{
return parent::make($name, $label)->separator(',')->options(
Options::make()->append('', 1)
diff --git a/src/Html/Editor/Fields/Checkbox.php b/src/Html/Editor/Fields/Checkbox.php
index ae02689..f55024e 100644
--- a/src/Html/Editor/Fields/Checkbox.php
+++ b/src/Html/Editor/Fields/Checkbox.php
@@ -4,5 +4,5 @@
class Checkbox extends Field
{
- protected $type = 'checkbox';
+ protected string $type = 'checkbox';
}
diff --git a/src/Html/Editor/Fields/Date.php b/src/Html/Editor/Fields/Date.php
index 7c689ba..99f7e8f 100644
--- a/src/Html/Editor/Fields/Date.php
+++ b/src/Html/Editor/Fields/Date.php
@@ -6,12 +6,8 @@ class Date extends DateTime
{
/**
* Make a new instance of a field.
- *
- * @param string $name
- * @param string $label
- * @return static|\Yajra\DataTables\Html\Editor\Fields\Field
*/
- public static function make($name, $label = '')
+ public static function make(array|string $name, string $label = ''): static
{
return parent::make($name, $label)->format('YYYY-MM-DD');
}
diff --git a/src/Html/Editor/Fields/DateTime.php b/src/Html/Editor/Fields/DateTime.php
index bb64673..de9824a 100644
--- a/src/Html/Editor/Fields/DateTime.php
+++ b/src/Html/Editor/Fields/DateTime.php
@@ -4,16 +4,12 @@
class DateTime extends Field
{
- protected $type = 'datetime';
+ protected string $type = 'datetime';
/**
* Make a new instance of a field.
- *
- * @param string $name
- * @param string $label
- * @return static|\Yajra\DataTables\Html\Editor\Fields\Field
*/
- public static function make($name, $label = '')
+ public static function make(array|string $name, string $label = ''): static
{
return parent::make($name, $label)->format('YYYY-MM-DD hh:mm a');
}
@@ -23,105 +19,141 @@ public static function make($name, $label = '')
*
* @return $this
*/
- public function military()
+ public function military(): static
{
return $this->format('YYYY-MM-DD HH:mm');
}
/**
- * @param \DateTime $dateTime
- * @param string $format
* @return $this
+ *
* @see https://editor.datatables.net/examples/dates/options-min-max.html
*/
- public function minDate(\DateTime $dateTime, $format = 'Y-m-d')
+ public function minDate(\DateTime $dateTime, string $format = 'Y-m-d'): static
{
- $this->attributes['opts']['minDate'] = "new Date('" . $dateTime->format($format) . "')";
-
- return $this;
+ return $this->opts(['minDate' => "new Date('".$dateTime->format($format)."')"]);
}
/**
- * @param \DateTime $dateTime
- * @param string $format
* @return $this
+ *
* @see https://editor.datatables.net/examples/dates/options-min-max.html
*/
- public function maxDate(\DateTime $dateTime, $format = 'Y-m-d')
+ public function maxDate(\DateTime $dateTime, string $format = 'Y-m-d'): static
{
- $this->attributes['opts']['maxDate'] = "new Date('" . $dateTime->format($format) . "')";
-
- return $this;
+ return $this->opts(['maxDate' => "new Date('".$dateTime->format($format)."')"]);
}
/**
- * @param bool $state
* @return $this
+ *
* @see https://editor.datatables.net/examples/dates/options-week-numbers.html
*/
- public function showWeekNumber($state = true)
+ public function showWeekNumber(bool $state = true): static
{
- $this->attributes['opts']['showWeekNumber'] = $state;
-
- return $this;
+ return $this->opts(['showWeekNumber' => $state]);
}
/**
- * @param array $days
* @return $this
+ *
* @see https://editor.datatables.net/examples/dates/options-disable-days.html
*/
- public function disableDays(array $days)
+ public function disableDays(array $days): static
{
- $this->attributes['opts']['disableDays'] = $days;
+ return $this->opts(['disableDays' => $days]);
+ }
- return $this;
+ /**
+ * @return $this
+ *
+ * @see https://editor.datatables.net/examples/dates/time-increment.html
+ */
+ public function minutesIncrement(int $minutes): static
+ {
+ return $this->opts(['minutesIncrement' => $minutes]);
}
/**
- * @param int $minutes
* @return $this
+ *
* @see https://editor.datatables.net/examples/dates/time-increment.html
*/
- public function minutesIncrement($minutes)
+ public function secondsIncrement(int $seconds): static
{
- $this->attributes['opts']['minutesIncrement'] = $minutes;
+ return $this->opts(['secondsIncrement' => $seconds]);
+ }
- return $this;
+ /**
+ * @return $this
+ *
+ * @see https://editor.datatables.net/examples/dates/datetime.html
+ */
+ public function hoursAvailable(array $hours): static
+ {
+ return $this->opts(['hoursAvailable' => $hours]);
}
/**
- * @param int $seconds
* @return $this
- * @see https://editor.datatables.net/examples/dates/time-increment.html
+ *
+ * @see https://editor.datatables.net/examples/dates/datetime.html
+ */
+ public function minutesAvailable(array $minutes): static
+ {
+ return $this->opts(['minutesAvailable' => $minutes]);
+ }
+
+ /**
+ * The format of the date string loaded from the server for the field's
+ * value and also for sending to the server on form submission.
+ * The formatting options are defined by Moment.js.
+ *
+ * @return $this
+ *
+ * @see https://editor.datatables.net/reference/field/datetime#Options
+ * @see https://momentjs.com/docs/#/displaying/format/
*/
- public function secondsIncrement($seconds)
+ public function wireFormat(string $format = 'YYYY-MM-DDTHH:mm:ss.000000Z'): static
{
- $this->attributes['opts']['secondsIncrement'] = $seconds;
+ $this->attributes['wireFormat'] = $format;
return $this;
}
/**
- * @param array $hours
+ * Allow (default), or disallow, the end user to type into the date / time input element.
+ * If disallowed, they must use the calendar picker to enter data. This can be useful
+ * if you are using a more complex date format and wish to disallow the user from
+ * potentially making typing mistakes, although note that it does also disallow
+ * pasting of data.
+ *
* @return $this
- * @see https://editor.datatables.net/examples/dates/datetime.html
+ *
+ * @see https://editor.datatables.net/reference/field/datetime#Options
*/
- public function hoursAvailable(array $hours)
+ public function keyInput(bool $state = true): static
{
- $this->attributes['opts']['hoursAvailable'] = $hours;
+ $this->attributes['keyInput'] = $state;
return $this;
}
/**
- * @param array $minutes
+ * The format of the date string that will be shown to the end user in the input element.
+ * The formatting options are defined by Moment.js. If a format is used that is not
+ * ISO8061 (i.e. YYYY-MM-DD) and Moment.js has not been included, Editor will
+ * throw an error stating that Moment.js must be included for custom
+ * formatting to be used.
+ *
* @return $this
- * @see https://editor.datatables.net/examples/dates/datetime.html
+ *
+ * @see https://editor.datatables.net/reference/field/datetime#Options
+ * @see https://momentjs.com/docs/#/displaying/format/
*/
- public function minutesAvailable(array $minutes)
+ public function displayFormat(string $format = 'YYYY-MM-DD hh:mm a'): static
{
- $this->attributes['opts']['minutesAvailable'] = $minutes;
+ $this->attributes['displayFormat'] = $format;
return $this;
}
diff --git a/src/Html/Editor/Fields/Field.php b/src/Html/Editor/Fields/Field.php
index 0dc37c0..f3c737a 100644
--- a/src/Html/Editor/Fields/Field.php
+++ b/src/Html/Editor/Fields/Field.php
@@ -2,9 +2,13 @@
namespace Yajra\DataTables\Html\Editor\Fields;
-use Illuminate\Support\Str;
-use Illuminate\Support\Fluent;
+use Closure;
use Illuminate\Contracts\Support\Arrayable;
+use Illuminate\Database\Eloquent\Builder;
+use Illuminate\Database\Query\Builder as QueryBuilder;
+use Illuminate\Support\Str;
+use Illuminate\Support\Traits\Macroable;
+use Yajra\DataTables\Html\Fluent;
use Yajra\DataTables\Html\HasAuthorizations;
/**
@@ -13,41 +17,36 @@
class Field extends Fluent
{
use HasAuthorizations;
+ use Macroable;
/**
* Field type.
- *
- * @var string
*/
- protected $type = 'text';
+ protected string $type = 'text';
/**
* Password constructor.
*
- * @param array $attributes
+ * @param array $attributes
*/
public function __construct($attributes = [])
{
- $attributes['type'] = $attributes['type'] ?? $this->type;
+ $attributes['type'] ??= $this->type;
parent::__construct($attributes);
}
/**
* Make a new instance of a field.
- *
- * @param string $name
- * @param string $label
- * @return static|\Yajra\DataTables\Html\Editor\Fields\Field
*/
- public static function make($name, $label = '')
+ public static function make(array|string $name, string $label = ''): static
{
if (is_array($name)) {
return new static($name);
}
$data = [
- 'name' => $name,
+ 'name' => $name,
'label' => $label ?: Str::title(str_replace('_', ' ', $name)),
];
@@ -55,11 +54,11 @@ public static function make($name, $label = '')
}
/**
- * @param string $label
* @return $this
+ *
* @see https://editor.datatables.net/reference/option/fields.label
*/
- public function label($label)
+ public function label(string $label): static
{
$this->attributes['label'] = $label;
@@ -67,11 +66,11 @@ public function label($label)
}
/**
- * @param string $name
* @return $this
+ *
* @see https://editor.datatables.net/reference/option/fields.name
*/
- public function name($name)
+ public function name(string $name): static
{
$this->attributes['name'] = $name;
@@ -79,11 +78,11 @@ public function name($name)
}
/**
- * @param string $data
* @return $this
+ *
* @see https://editor.datatables.net/reference/option/fields.data
*/
- public function data($data)
+ public function data(string $data): static
{
$this->attributes['data'] = $data;
@@ -91,13 +90,14 @@ public function data($data)
}
/**
- * @param string $type
* @return $this
+ *
* @see https://editor.datatables.net/reference/option/fields.type
*/
- public function type($type)
+ public function type(string $type): static
{
$this->attributes['type'] = $type;
+ $this->type = $type;
return $this;
}
@@ -105,25 +105,40 @@ public function type($type)
/**
* Get options from a model.
*
- * @param mixed $model
- * @param string $value
- * @param string $key
+ * @param \Illuminate\Database\Eloquent\Builder|class-string<\Illuminate\Database\Eloquent\Model> $model
* @return $this
*/
- public function modelOptions($model, $value, $key = 'id')
+ public function modelOptions(Builder|string $model, string $value, string $key = 'id'): static
{
return $this->options(
Options::model($model, $value, $key)
);
}
+ /**
+ * Get options from a Enum::cases().
+ *
+ * @return $this
+ */
+ public function enumOptions(array $cases): static
+ {
+ $options = [];
+ foreach ($cases as $case) {
+ $options[] = [
+ 'value' => $case->value,
+ 'label' => $case->value,
+ ];
+ }
+
+ return $this->options($options);
+ }
+
/**
* Set select options.
*
- * @param array|mixed $options
* @return $this
*/
- public function options($options)
+ public function options(array|Arrayable $options): static
{
if ($options instanceof Arrayable) {
$options = $options->toArray();
@@ -137,15 +152,15 @@ public function options($options)
/**
* Get options from a table.
*
- * @param mixed $table
- * @param string $value
- * @param string $key
- * @param \Closure $whereCallback
- * @param string|null $key
* @return $this
*/
- public function tableOptions($table, $value, $key = 'id', \Closure $whereCallback = null, $connection = null)
- {
+ public function tableOptions(
+ QueryBuilder|Closure|string $table,
+ string $value,
+ string $key = 'id',
+ ?Closure $whereCallback = null,
+ ?string $connection = null
+ ): static {
return $this->options(
Options::table($table, $value, $key, $whereCallback, $connection)
);
@@ -154,10 +169,9 @@ public function tableOptions($table, $value, $key = 'id', \Closure $whereCallbac
/**
* Set checkbox separator.
*
- * @param string $separator
* @return $this
*/
- public function separator($separator = ',')
+ public function separator(string $separator = ','): static
{
$this->attributes['separator'] = $separator;
@@ -167,11 +181,11 @@ public function separator($separator = ',')
/**
* Set dateTime format.
*
- * @param string $format
* @return $this
+ *
* @see https://editor.datatables.net/reference/field/datetime
*/
- public function format($format)
+ public function format(string $format): static
{
$this->attributes['format'] = $format;
@@ -181,11 +195,11 @@ public function format($format)
/**
* Set field default value.
*
- * @param mixed $value
* @return $this
+ *
* @see https://editor.datatables.net/reference/option/fields.def
*/
- public function default($value)
+ public function default(float|bool|int|string|array $value): static
{
$this->attributes['def'] = $value;
@@ -195,11 +209,11 @@ public function default($value)
/**
* Set field message value.
*
- * @param string $value
* @return $this
+ *
* @see https://editor.datatables.net/reference/option/fields.message
*/
- public function message($value)
+ public function message(string $value): static
{
$this->attributes['message'] = $value;
@@ -209,11 +223,11 @@ public function message($value)
/**
* Set field fieldInfo value.
*
- * @param string $value
* @return $this
+ *
* @see https://editor.datatables.net/reference/option/fields.fieldInfo
*/
- public function fieldInfo($value)
+ public function fieldInfo(string $value): static
{
$this->attributes['fieldInfo'] = $value;
@@ -223,11 +237,11 @@ public function fieldInfo($value)
/**
* Set field labelInfo value.
*
- * @param string $value
* @return $this
+ *
* @see https://editor.datatables.net/reference/option/fields.labelInfo
*/
- public function labelInfo($value)
+ public function labelInfo(string $value): static
{
$this->attributes['labelInfo'] = $value;
@@ -237,11 +251,11 @@ public function labelInfo($value)
/**
* Set field entityDecode value.
*
- * @param mixed|bool $value
* @return $this
+ *
* @see https://editor.datatables.net/reference/option/fields.entityDecode
*/
- public function entityDecode($value)
+ public function entityDecode(bool $value): static
{
$this->attributes['entityDecode'] = $value;
@@ -251,11 +265,11 @@ public function entityDecode($value)
/**
* Set field multiEditable value.
*
- * @param mixed|bool $value
* @return $this
+ *
* @see https://editor.datatables.net/reference/option/fields.multiEditable
*/
- public function multiEditable($value)
+ public function multiEditable(bool $value): static
{
$this->attributes['multiEditable'] = $value;
@@ -265,11 +279,11 @@ public function multiEditable($value)
/**
* Set field id value.
*
- * @param string $value
* @return $this
+ *
* @see https://editor.datatables.net/reference/option/fields.id
*/
- public function id($value)
+ public function id(string $value): static
{
$this->attributes['id'] = $value;
@@ -279,11 +293,11 @@ public function id($value)
/**
* Set field submit value.
*
- * @param bool $value
* @return $this
+ *
* @see https://editor.datatables.net/reference/option/fields.submit
*/
- public function submit($value)
+ public function submit(bool $value): static
{
$this->attributes['submit'] = $value;
@@ -293,11 +307,11 @@ public function submit($value)
/**
* Set field compare value.
*
- * @param bool $value
* @return $this
+ *
* @see https://editor.datatables.net/reference/option/fields.compare
*/
- public function compare($value)
+ public function compare(bool $value): static
{
$this->attributes['compare'] = $value;
@@ -307,26 +321,69 @@ public function compare($value)
/**
* Set field opts value.
*
- * @param bool $value
* @return $this
+ *
+ * @see https://datatables.net/forums/discussion/comment/156581/#Comment_156581
+ */
+ public function opts(array $value): static
+ {
+ if (! isset($this->attributes['opts'])) {
+ $this->attributes['opts'] = $value;
+ } else {
+ $this->attributes['opts'] = array_merge((array) $this->attributes['opts'], $value);
+ }
+
+ return $this;
+ }
+
+ /**
+ * Set field element html attributes.
+ *
+ * @return $this
+ *
+ * @see https://datatables.net/forums/discussion/comment/156581/#Comment_156581
*/
- public function opts(array $value)
+ public function attr(string $attribute, int|bool|string $value): static
{
- $this->attributes['opts'] = $value;
+ if (! isset($this->attributes['attr'])) {
+ $this->attributes['attr'] = [];
+ }
+
+ $attributes = (array) $this->attributes['attr'];
+ $attributes[$attribute] = $value;
+
+ $this->attributes['attr'] = $attributes;
return $this;
}
+ public function getType(): string
+ {
+ return $this->type;
+ }
+
/**
- * Set field attr option.
+ * Replace null values with the field's default on edit.
*
- * @param string $attribute
- * @param mixed $value
* @return $this
+ *
+ * @see https://editor.datatables.net/reference/option/fields.nullDefault
+ */
+ public function nullDefault(bool $value = true): static
+ {
+ $this->attributes['nullDefault'] = $value;
+
+ return $this;
+ }
+
+ /**
+ * @return $this
+ *
+ * @see https://editor.datatables.net/reference/option/fields.className
*/
- public function attr($attribute, $value)
+ public function className(string $className): static
{
- $this->attributes['attr'][$attribute] = $value;
+ $this->attributes['className'] = $className;
return $this;
}
diff --git a/src/Html/Editor/Fields/File.php b/src/Html/Editor/Fields/File.php
index 265d9fe..a10a8c6 100644
--- a/src/Html/Editor/Fields/File.php
+++ b/src/Html/Editor/Fields/File.php
@@ -9,33 +9,24 @@
*/
class File extends Field
{
- protected $type = 'upload';
+ protected string $type = 'upload';
/**
- * Editor instance.
- *
- * @var string
+ * Editor instance variable name.
*/
- protected $editor = 'editor';
+ protected string $editor = 'editor';
- /**
- * @param string $name
- * @param string $label
- * @return static|\Yajra\DataTables\Html\Editor\Fields\Field
- */
- public static function make($name, $label = '')
+ public static function make(array|string $name, string $label = ''): static
{
- /** @var \Yajra\DataTables\Html\Editor\Fields\File $field */
$field = parent::make($name, $label);
return $field->displayFile()->clearText()->noImageText();
}
/**
- * @param string $value
* @return $this
*/
- public function ajax($value)
+ public function ajax(string $value): static
{
$this->attributes['ajax'] = $value;
@@ -43,10 +34,9 @@ public function ajax($value)
}
/**
- * @param string $value
* @return $this
*/
- public function ajaxData($value)
+ public function ajaxData(string $value): static
{
$this->attributes['ajaxData'] = $value;
@@ -54,10 +44,9 @@ public function ajaxData($value)
}
/**
- * @param bool $value
* @return $this
*/
- public function dragDrop($value = true)
+ public function dragDrop(bool $value = true): static
{
$this->attributes['dragDrop'] = $value;
@@ -65,10 +54,9 @@ public function dragDrop($value = true)
}
/**
- * @param string $value
* @return $this
*/
- public function dragDropText($value)
+ public function dragDropText(string $value): static
{
$this->attributes['dragDropText'] = $value;
@@ -76,10 +64,9 @@ public function dragDropText($value)
}
/**
- * @param string $value
* @return $this
*/
- public function fileReadText($value)
+ public function fileReadText(string $value): static
{
$this->attributes['fileReadText'] = $value;
@@ -87,10 +74,9 @@ public function fileReadText($value)
}
/**
- * @param string $value
* @return $this
*/
- public function noFileText($value)
+ public function noFileText(string $value): static
{
$this->attributes['noFileText'] = $value;
@@ -98,10 +84,9 @@ public function noFileText($value)
}
/**
- * @param string $value
* @return $this
*/
- public function processingText($value)
+ public function processingText(string $value): static
{
$this->attributes['processingText'] = $value;
@@ -109,10 +94,9 @@ public function processingText($value)
}
/**
- * @param string $value
* @return $this
*/
- public function uploadText($value)
+ public function uploadText(string $value): static
{
$this->attributes['uploadText'] = $value;
@@ -122,10 +106,9 @@ public function uploadText($value)
/**
* Set editor instance for file upload.
*
- * @param string $editor
* @return $this
*/
- public function editor($editor)
+ public function editor(string $editor): static
{
$this->editor = $editor;
@@ -137,16 +120,21 @@ public function editor($editor)
*
* @return $this
*/
- public function displayImage()
+ public function displayImage(): static
{
- return $this->display("function (file_id) { return file_id ? '
' : null; }");
+ // TODO: Use Laravel filesystem instead of hard coded storage path
+ return $this->display(<<<'SCRIPT'
+ function (file_id) {
+ return file_id ? '
' : null;
+ }
+SCRIPT
+ );
}
/**
- * @param string $value
* @return $this
*/
- public function display($value)
+ public function display(string $value): static
{
$this->attributes['display'] = $value;
@@ -158,16 +146,15 @@ public function display($value)
*
* @return $this
*/
- public function displayFile()
+ public function displayFile(): static
{
- return $this->display("function (file_id) { return file_id; }");
+ return $this->display('function (file_id) { return file_id; }');
}
/**
- * @param string $value
* @return $this
*/
- public function clearText($value = 'Clear')
+ public function clearText(string $value = 'Clear'): static
{
$this->attributes['clearText'] = $value;
@@ -175,10 +162,9 @@ public function clearText($value = 'Clear')
}
/**
- * @param string $value
* @return $this
*/
- public function noImageText($value = 'No image')
+ public function noImageText(string $value = 'No image'): static
{
$this->attributes['noImageText'] = $value;
@@ -186,10 +172,9 @@ public function noImageText($value = 'No image')
}
/**
- * @param bool $state
* @return $this
*/
- public function multiple($state = true)
+ public function multiple(bool $state = true): static
{
if ($state) {
$this->type('uploadMany');
diff --git a/src/Html/Editor/Fields/Hidden.php b/src/Html/Editor/Fields/Hidden.php
index de9288d..b7e27af 100644
--- a/src/Html/Editor/Fields/Hidden.php
+++ b/src/Html/Editor/Fields/Hidden.php
@@ -4,5 +4,5 @@
class Hidden extends Field
{
- protected $type = 'hidden';
+ protected string $type = 'hidden';
}
diff --git a/src/Html/Editor/Fields/Image.php b/src/Html/Editor/Fields/Image.php
index 608b2d8..5f3eb8e 100644
--- a/src/Html/Editor/Fields/Image.php
+++ b/src/Html/Editor/Fields/Image.php
@@ -9,14 +9,9 @@
*/
class Image extends File
{
- protected $type = 'upload';
+ protected string $type = 'upload';
- /**
- * @param string $name
- * @param string $label
- * @return \Yajra\DataTables\Html\Editor\Fields\File
- */
- public static function make($name, $label = '')
+ public static function make(array|string $name, string $label = ''): static
{
return parent::make($name, $label)->displayImage();
}
diff --git a/src/Html/Editor/Fields/Number.php b/src/Html/Editor/Fields/Number.php
index 560a90d..9dde165 100644
--- a/src/Html/Editor/Fields/Number.php
+++ b/src/Html/Editor/Fields/Number.php
@@ -4,7 +4,7 @@
class Number extends Field
{
- public static function make($name, $label = '')
+ public static function make(array|string $name, string $label = ''): static
{
return parent::make($name, $label)->attr('type', 'number');
}
diff --git a/src/Html/Editor/Fields/Options.php b/src/Html/Editor/Fields/Options.php
index 97eafde..dfd1509 100644
--- a/src/Html/Editor/Fields/Options.php
+++ b/src/Html/Editor/Fields/Options.php
@@ -2,18 +2,23 @@
namespace Yajra\DataTables\Html\Editor\Fields;
-use Illuminate\Database\Eloquent\Builder;
+use Closure;
+use Illuminate\Contracts\Database\Eloquent\Builder as EloquentBuilder;
+use Illuminate\Database\Eloquent\Model;
+use Illuminate\Database\Query\Builder;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\DB;
+/**
+ * @template TKey of array-key
+ * @template TValue
+ */
class Options extends Collection
{
/**
* Return a Yes/No options.
- *
- * @return Options
*/
- public static function yesNo()
+ public static function yesNo(): static
{
$data = [
['label' => __('Yes'), 'value' => 1],
@@ -26,54 +31,45 @@ public static function yesNo()
/**
* Get options from a model.
*
- * @param mixed $model
- * @param string $value
- * @param string $key
- * @return Collection
+ * @param class-string|\Illuminate\Database\Eloquent\Builder $model
*/
- public static function model($model, $value, $key = 'id')
+ public static function model(string|EloquentBuilder $model, string $value, string $key = 'id'): Collection
{
- if (! $model instanceof Builder) {
+ if (! $model instanceof EloquentBuilder) {
$model = $model::query();
}
- return $model->get()->map(function ($model) use ($value, $key) {
- return [
- 'value' => $model->{$key},
- 'label' => $model->{$value},
- ];
- });
+ return $model->get()->map(fn ($model) => [
+ 'value' => $model->{$key},
+ 'label' => $model->{$value},
+ ]);
}
/**
* Get options from a table.
- *
- * @param mixed $table
- * @param string $value
- * @param string $key
- * @param \Closure $whereCallback
- * @param string|null $key
- * @return Collection
*/
- public static function table($table, $value, $key = 'id', \Closure $whereCallback = null, $connection = null)
- {
+ public static function table(
+ Closure|Builder|string $table,
+ string $value,
+ string $key = 'id',
+ ?Closure $callback = null,
+ ?string $connection = null
+ ): Collection {
$query = DB::connection($connection)
- ->table($table)
- ->select("{$value} as label", "{$key} as value");
+ ->table($table)
+ ->select("$value as label", "$key as value");
- if ($whereCallback) {
- $query->where($whereCallback);
+ if (is_callable($callback)) {
+ $callback($query);
}
- return $query->get();
+ return $query->get()->map(fn ($row) => (array) $row);
}
/**
* Return a True/False options.
- *
- * @return Options
*/
- public static function trueFalse()
+ public static function trueFalse(): static
{
$data = [
['label' => __('True'), 'value' => 1],
@@ -85,12 +81,8 @@ public static function trueFalse()
/**
* Push an item onto the end of the collection.
- *
- * @param mixed $value
- * @param mixed $key
- * @return Options
*/
- public function append($value, $key)
+ public function append(string $value, int|string $key): static
{
return $this->push(['label' => $value, 'value' => $key]);
}
@@ -98,11 +90,10 @@ public function append($value, $key)
/**
* Push an item onto the beginning of the collection.
*
- * @param mixed $value
- * @param mixed $key
- * @return \Illuminate\Support\Collection
+ * @param TValue $value
+ * @param TKey $key
*/
- public function prepend($value, $key = null)
+ public function prepend($value, $key = null): static
{
$data = ['label' => $value, 'value' => $key];
diff --git a/src/Html/Editor/Fields/Password.php b/src/Html/Editor/Fields/Password.php
index 6e5a3a6..fa201ed 100644
--- a/src/Html/Editor/Fields/Password.php
+++ b/src/Html/Editor/Fields/Password.php
@@ -4,5 +4,5 @@
class Password extends Field
{
- protected $type = 'password';
+ protected string $type = 'password';
}
diff --git a/src/Html/Editor/Fields/Radio.php b/src/Html/Editor/Fields/Radio.php
index b49a706..9f3dc43 100644
--- a/src/Html/Editor/Fields/Radio.php
+++ b/src/Html/Editor/Fields/Radio.php
@@ -4,5 +4,5 @@
class Radio extends Field
{
- protected $type = 'radio';
+ protected string $type = 'radio';
}
diff --git a/src/Html/Editor/Fields/ReadOnly.php b/src/Html/Editor/Fields/ReadOnly.php
deleted file mode 100644
index d1b6f6e..0000000
--- a/src/Html/Editor/Fields/ReadOnly.php
+++ /dev/null
@@ -1,8 +0,0 @@
-attributes['multiple'] = $value;
@@ -25,17 +24,17 @@ public function multiple(bool $value = true)
/**
* Set field optionsPair value.
*
- * @param string|array $label
- * @param string $value
* @return $this
*/
- public function optionsPair($label = 'label', $value = 'value')
+ public function optionsPair(array|string $label = 'label', string $value = 'value'): static
{
if (is_array($label)) {
$this->attributes['optionsPair'] = $label;
} else {
- $this->attributes['optionsPair']['label'] = $label;
- $this->attributes['optionsPair']['value'] = $value;
+ $this->attributes['optionsPair'] = [
+ 'label' => $label,
+ 'value' => $value,
+ ];
}
return $this;
@@ -44,10 +43,9 @@ public function optionsPair($label = 'label', $value = 'value')
/**
* Set field placeholder value.
*
- * @param string $value
* @return $this
*/
- public function placeholder($value)
+ public function placeholder(string $value): static
{
$this->attributes['placeholder'] = $value;
@@ -57,10 +55,9 @@ public function placeholder($value)
/**
* Set field placeholderDisabled value.
*
- * @param bool $value
* @return $this
*/
- public function placeholderDisabled(bool $value)
+ public function placeholderDisabled(bool $value): static
{
$this->attributes['placeholderDisabled'] = $value;
@@ -70,10 +67,9 @@ public function placeholderDisabled(bool $value)
/**
* Set field placeholderValue value.
*
- * @param string $value
* @return $this
*/
- public function placeholderValue($value)
+ public function placeholderValue(string $value): static
{
$this->attributes['placeholderValue'] = $value;
diff --git a/src/Html/Editor/Fields/Select2.php b/src/Html/Editor/Fields/Select2.php
index 4d28b12..e16f045 100644
--- a/src/Html/Editor/Fields/Select2.php
+++ b/src/Html/Editor/Fields/Select2.php
@@ -7,114 +7,110 @@
*/
class Select2 extends Select
{
- protected $type = 'select2';
+ protected string $type = 'select2';
/**
- * @param bool $state
* @return $this
*/
- public function allowClear($state = true)
+ public function allowClear(bool $state = true): static
{
- $this->attributes['opts']['allowClear'] = $state;
+ return $this->opts(['allowClear' => $state]);
+ }
- return $this;
+ /**
+ * @return $this
+ */
+ public function placeholder(string $value): static
+ {
+ return $this->optsPlaceholder($value);
}
/**
- * @param string $text
- * @param string|null $id
* @return $this
*/
- public function placeholder($text = '', $id = null)
+ public function optsPlaceholder(string $text = '', string $id = ''): static
{
- $this->attributes['opts']['placeholder'] = [
- 'id' => $id,
- 'text' => $text,
- ];
+ return $this->opts([
+ 'placeholder' => [
+ 'id' => $id,
+ 'text' => $text,
+ ],
+ ]);
+ }
- return $this;
+ public function multiple(bool $value = true): static
+ {
+ return $this->opts(['multiple' => $value]);
}
/**
* Set select2 ajax option.
*
- * @param mixed $value
* @return $this
*/
- public function ajax($value)
+ public function ajax(array|string $value): static
{
+ $ajax = $this->opts['ajax'] ?? [];
+
if (is_array($value)) {
- $this->attributes['opts']['ajax'] = $value;
- } else {
- $this->attributes['opts']['ajax']['url'] = $value;
+ return $this->opts(['ajax' => array_merge($ajax, $value)]);
}
- return $this;
+ return $this->opts(['ajax' => array_merge($ajax, ['url' => $value])]);
}
/**
* Set select2 ajax url option.
*
- * @param mixed $value
* @return $this
*/
- public function ajaxUrl($value)
+ public function ajaxUrl(string $value): static
{
- $this->attributes['opts']['ajax']['url'] = $value;
-
- return $this;
+ return $this->ajax(['url' => $value]);
}
/**
* Set select2 ajaxDelay option.
*
- * @param mixed $value
* @return $this
*/
- public function ajaxDelay($value = 250)
+ public function ajaxDelay(int $value = 250): static
{
- $this->attributes['opts']['ajax']['delay'] = $value;
-
- return $this;
+ return $this->ajax(['delay' => $value]);
}
/**
* Set select2 ajax data option.
*
- * @param mixed $data
* @return $this
*/
- public function ajaxData($data)
+ public function ajaxData(array|string $data): static
{
if (is_array($data)) {
$script = 'function(params) {';
foreach ($data as $key => $value) {
- $value = json_encode($value);
- $script .= " params.{$key} = {$value}; ";
+ $value = json_encode($value, JSON_THROW_ON_ERROR);
+ $script .= " params.$key = $value; ";
}
$script .= 'return params; }';
$data = $script;
}
- $this->attributes['opts']['ajax']['data'] = $data;
-
- return $this;
+ return $this->ajax(['data' => $data]);
}
/**
* Set select2 ajax processResults option to process a paginated results.
*
- * @param string $display
- * @param string $id
* @return $this
*/
- public function processPaginatedResults($display = 'text', $id = 'id')
+ public function processPaginatedResults(string $display = 'text', string $id = 'id', string $wrap = 'results'): static
{
$script = 'function(data, params) { ';
$script .= 'params.page = params.page || 1; ';
- $script .= "data.data.map(function(e) { e.text = e.{$display}; e.id = e.{$id}; return e; }); ";
- $script .= 'return { results: data.data, pagination: { more: data.current_page < data.last_page } };';
+ $script .= "data.$wrap.map(function(e) { e.text = e.$display; e.id = e.$id; return e; }); ";
+ $script .= "return { results: data.$wrap, pagination: { more: data.meta.current_page < data.meta.last_page } };";
$script .= '}';
return $this->processResults($script);
@@ -123,13 +119,10 @@ public function processPaginatedResults($display = 'text', $id = 'id')
/**
* Set select2 ajax processResults option.
*
- * @param string $value
* @return $this
*/
- public function processResults($value)
+ public function processResults(string $value): static
{
- $this->attributes['opts']['ajax']['processResults'] = $value;
-
- return $this;
+ return $this->ajax(['processResults' => $value]);
}
}
diff --git a/src/Html/Editor/Fields/Tags.php b/src/Html/Editor/Fields/Tags.php
new file mode 100644
index 0000000..2b910be
--- /dev/null
+++ b/src/Html/Editor/Fields/Tags.php
@@ -0,0 +1,143 @@
+attributes['ajax'] = $url;
+
+ return $this;
+ }
+
+ /**
+ * @see https://editor.datatables.net/reference/field/tags#display
+ */
+ public function display(string $display): static
+ {
+ $this->attributes['display'] = $display;
+
+ return $this;
+ }
+
+ /**
+ * @see https://editor.datatables.net/reference/field/tags#escapeLabelHtml
+ */
+ public function escapeLabelHtml(bool $escape): static
+ {
+ $this->attributes['escapeLabelHtml'] = $escape;
+
+ return $this;
+ }
+
+ /**
+ * @see https://editor.datatables.net/reference/field/tags#i18n
+ */
+ public function i18n(array $i18n): static
+ {
+ $options = isset($this->attributes['i18n'])
+ ? (array) $this->attributes['i18n']
+ : [];
+
+ $this->attributes['i18n'] = array_merge($options, $i18n);
+
+ return $this;
+ }
+
+ /**
+ * @see https://editor.datatables.net/reference/field/tags#i18n
+ */
+ public function addButton(string $text): static
+ {
+ return $this->i18n(['addButton' => $text]);
+ }
+
+ /**
+ * @see https://editor.datatables.net/reference/field/tags#i18n
+ */
+ public function inputPlaceholder(string $text): static
+ {
+ return $this->i18n(['inputPlaceholder' => $text]);
+ }
+
+ /**
+ * @see https://editor.datatables.net/reference/field/tags#i18n
+ */
+ public function noResults(string $text): static
+ {
+ return $this->i18n(['noResults' => $text]);
+ }
+
+ /**
+ * @see https://editor.datatables.net/reference/field/tags#i18n
+ */
+ public function title(string $text): static
+ {
+ return $this->i18n(['title' => $text]);
+ }
+
+ /**
+ * @see https://editor.datatables.net/reference/field/tags#i18n
+ */
+ public function placeholder(string $text): static
+ {
+ return $this->i18n(['placeholder' => $text]);
+ }
+
+ /**
+ * @see https://editor.datatables.net/reference/field/tags#limit
+ */
+ public function limit(int $limit): static
+ {
+ $this->attributes['limit'] = $limit;
+
+ return $this;
+ }
+
+ /**
+ * @see https://editor.datatables.net/reference/field/tags#multiple
+ */
+ public function multiple(bool $multiple = true): static
+ {
+ $this->attributes['multiple'] = $multiple;
+
+ return $this;
+ }
+
+ /**
+ * @see https://editor.datatables.net/reference/field/tags#options
+ */
+ public function options(array|Arrayable $options): static
+ {
+ return parent::options($options);
+ }
+
+ /**
+ * @see https://editor.datatables.net/reference/field/tags#separator
+ */
+ public function separator(string $separator = ','): static
+ {
+ return parent::separator($separator);
+ }
+
+ /**
+ * @see https://editor.datatables.net/reference/field/tags#unique
+ */
+ public function unique(bool $unique = true): static
+ {
+ $this->attributes['unique'] = $unique;
+
+ return $this;
+ }
+}
diff --git a/src/Html/Editor/Fields/Text.php b/src/Html/Editor/Fields/Text.php
index 2e5c502..7e89242 100644
--- a/src/Html/Editor/Fields/Text.php
+++ b/src/Html/Editor/Fields/Text.php
@@ -2,6 +2,4 @@
namespace Yajra\DataTables\Html\Editor\Fields;
-class Text extends Field
-{
-}
+class Text extends Field {}
diff --git a/src/Html/Editor/Fields/TextArea.php b/src/Html/Editor/Fields/TextArea.php
index 15dcdc9..666bc1e 100644
--- a/src/Html/Editor/Fields/TextArea.php
+++ b/src/Html/Editor/Fields/TextArea.php
@@ -4,22 +4,14 @@
class TextArea extends Field
{
- protected $type = 'textarea';
+ protected string $type = 'textarea';
- /**
- * @param int $value
- * @return static
- */
- public function rows($value)
+ public function rows(int $value): static
{
return $this->attr('rows', $value);
}
- /**
- * @param int $value
- * @return static
- */
- public function cols($value)
+ public function cols(int $value): static
{
return $this->attr('cols', $value);
}
diff --git a/src/Html/Editor/Fields/Time.php b/src/Html/Editor/Fields/Time.php
index f457463..1923b46 100644
--- a/src/Html/Editor/Fields/Time.php
+++ b/src/Html/Editor/Fields/Time.php
@@ -6,14 +6,9 @@ class Time extends DateTime
{
/**
* Make a new instance of a field.
- *
- * @param string $name
- * @param string $label
- * @return static|\Yajra\DataTables\Html\Editor\Fields\File
*/
- public static function make($name, $label = '')
+ public static function make(array|string $name, string $label = ''): static
{
- /** @var \Yajra\DataTables\Html\Editor\Fields\Time $field */
$field = parent::make($name, $label);
return $field->format('hh:mm a');
@@ -24,7 +19,7 @@ public static function make($name, $label = '')
*
* @return $this
*/
- public function military()
+ public function military(): static
{
return $this->format('HH:mm');
}
diff --git a/src/Html/Editor/FormOptions.php b/src/Html/Editor/FormOptions.php
index 475faef..03c149c 100644
--- a/src/Html/Editor/FormOptions.php
+++ b/src/Html/Editor/FormOptions.php
@@ -2,27 +2,24 @@
namespace Yajra\DataTables\Html\Editor;
-use Illuminate\Support\Fluent;
+use Yajra\DataTables\Html\Fluent;
/**
* @see https://editor.datatables.net/reference/type/form-options
*/
class FormOptions extends Fluent
{
- /**
- * @param array $attributes
- * @return \Yajra\DataTables\Html\Editor\FormOptions
- */
- public static function make($attributes = [])
+ public static function make(array $attributes = []): static
{
return new static($attributes);
}
/**
- * @param int $value
* @return $this
+ *
+ * @see https://editor.datatables.net/reference/type/form-options#focus
*/
- public function focus($value = 0)
+ public function focus(int|string|null $value = null): static
{
$this->attributes['focus'] = $value;
@@ -30,21 +27,23 @@ public function focus($value = 0)
}
/**
- * @param bool $value
* @return $this
+ *
+ * @see https://editor.datatables.net/reference/type/form-options#nest
*/
- public function message($value = false)
+ public function nest(bool $value): static
{
- $this->attributes['message'] = $value;
+ $this->attributes['nest'] = $value;
return $this;
}
/**
- * @param string $value
* @return $this
+ *
+ * @see https://editor.datatables.net/reference/type/form-options#onBackground
*/
- public function onBackground($value = 'blur')
+ public function onBackground(string $value = 'blur'): static
{
$this->attributes['onBackground'] = $value;
@@ -52,10 +51,11 @@ public function onBackground($value = 'blur')
}
/**
- * @param string $value
* @return $this
+ *
+ * @see https://editor.datatables.net/reference/type/form-options#onBlur
*/
- public function onBlur($value = 'close')
+ public function onBlur(string $value = 'close'): static
{
$this->attributes['onBlur'] = $value;
@@ -63,10 +63,11 @@ public function onBlur($value = 'close')
}
/**
- * @param string $value
* @return $this
+ *
+ * @see https://editor.datatables.net/reference/type/form-options#onComplete
*/
- public function onComplete($value = 'close')
+ public function onComplete(string $value = 'close'): static
{
$this->attributes['onComplete'] = $value;
@@ -74,10 +75,11 @@ public function onComplete($value = 'close')
}
/**
- * @param string $value
* @return $this
+ *
+ * @see https://editor.datatables.net/reference/type/form-options#onEsc
*/
- public function onEsc($value = 'close')
+ public function onEsc(string $value = 'close'): static
{
$this->attributes['onEsc'] = $value;
@@ -85,10 +87,11 @@ public function onEsc($value = 'close')
}
/**
- * @param string $value
* @return $this
+ *
+ * @see https://editor.datatables.net/reference/type/form-options#onFieldError
*/
- public function onFieldError($value = 'focus')
+ public function onFieldError(string $value = 'focus'): static
{
$this->attributes['onFieldError'] = $value;
@@ -96,10 +99,11 @@ public function onFieldError($value = 'focus')
}
/**
- * @param string $value
* @return $this
+ *
+ * @see https://editor.datatables.net/reference/type/form-options#onReturn
*/
- public function onReturn($value = 'submit')
+ public function onReturn(string $value = 'submit'): static
{
$this->attributes['onReturn'] = $value;
@@ -107,10 +111,11 @@ public function onReturn($value = 'submit')
}
/**
- * @param string $value
* @return $this
+ *
+ * @see https://editor.datatables.net/reference/type/form-options#submit
*/
- public function submit($value = 'changed')
+ public function submit(string $value = 'changed'): static
{
$this->attributes['submit'] = $value;
@@ -118,21 +123,35 @@ public function submit($value = 'changed')
}
/**
- * @param bool $value
* @return $this
+ *
+ * @see https://editor.datatables.net/reference/type/form-options#scope
*/
- public function title($value = false)
+ public function formScope(string $value = 'row'): static
{
- $this->attributes['title'] = $value;
+ $this->attributes['scope'] = $value;
+
+ return $this;
+ }
+
+ /**
+ * @return $this
+ *
+ * @see https://editor.datatables.net/reference/type/form-options#buttons
+ */
+ public function buttons(array|string $value): static
+ {
+ $this->attributes['buttons'] = $value;
return $this;
}
/**
- * @param bool $value
* @return $this
+ *
+ * @see https://editor.datatables.net/reference/type/form-options#drawType
*/
- public function drawType($value = false)
+ public function drawType(string $value = ''): static
{
$this->attributes['drawType'] = $value;
@@ -140,12 +159,49 @@ public function drawType($value = false)
}
/**
- * @param string $value
* @return $this
+ *
+ * @see https://editor.datatables.net/reference/type/form-options#message
*/
- public function scope($value = 'row')
+ public function message(bool|string $value = ''): static
{
- $this->attributes['scope'] = $value;
+ $this->attributes['message'] = $value;
+
+ return $this;
+ }
+
+ /**
+ * @return $this
+ *
+ * @see https://editor.datatables.net/reference/type/form-options#submitTrigger
+ */
+ public function submitTrigger(int|string $value): static
+ {
+ $this->attributes['submitTrigger'] = $value;
+
+ return $this;
+ }
+
+ /**
+ * @return $this
+ *
+ * @see https://editor.datatables.net/reference/type/form-options#submitHtml
+ */
+ public function submitHtml(string $value): static
+ {
+ $this->attributes['submitHtml'] = $value;
+
+ return $this;
+ }
+
+ /**
+ * @return $this
+ *
+ * @see https://editor.datatables.net/reference/type/form-options#title
+ */
+ public function title(bool|string $value): static
+ {
+ $this->attributes['title'] = $value;
return $this;
}
diff --git a/src/Html/Editor/HasEvents.php b/src/Html/Editor/HasEvents.php
index 67581db..ee57589 100644
--- a/src/Html/Editor/HasEvents.php
+++ b/src/Html/Editor/HasEvents.php
@@ -5,72 +5,75 @@
use Illuminate\Support\Str;
/**
- * @method Editor onClose($script)
- * @method Editor onCreate($script)
- * @method Editor onDisplayOrder($script)
- * @method Editor onEdit($script)
- * @method Editor onInitCreate($script)
- * @method Editor onInitEdit($script)
- * @method Editor onInitRemove($script)
- * @method Editor onInitSubmit($script)
- * @method Editor onOpen($script)
- * @method Editor onPostCreate($script)
- * @method Editor onPostEdit($script)
- * @method Editor onPostRemove($script)
- * @method Editor onPostSubmit($script)
- * @method Editor onPostUpload($script)
- * @method Editor onPreBlur($script)
- * @method Editor onPreBlurCancelled($script)
- * @method Editor onPreCreate($script)
- * @method Editor onPreEdit($script)
- * @method Editor onPreOpen($script)
- * @method Editor onPreOpenCancelled($script)
- * @method Editor onPreRemove($script)
- * @method Editor onPreSubmit($script)
- * @method Editor onPreSubmitCancelled($script)
- * @method Editor onPreUpload($script)
- * @method Editor onPreUploadCancelled($script)
- * @method Editor onProcessing($script)
- * @method Editor onRemove($script)
- * @method Editor onSetData($script)
- * @method Editor onSubmitComplete($script)
- * @method Editor onSubmitError($script)
- * @method Editor onSubmitSuccess($script)
- * @method Editor onSubmitUnsuccessful($script)
- * @method Editor onUploadXhrError($script)
- * @method Editor onUploadXhrSuccess($script)
+ * @method $this onClose($script)
+ * @method $this onClosed($script)
+ * @method $this onCreate($script)
+ * @method $this onDisplayOrder($script)
+ * @method $this onEdit($script)
+ * @method $this onInitCreate($script)
+ * @method $this onInitEdit($script)
+ * @method $this onInitEditor($script)
+ * @method $this onInitRemove($script)
+ * @method $this onInitSubmit($script)
+ * @method $this onOpen($script)
+ * @method $this onOpened($script)
+ * @method $this onPostCreate($script)
+ * @method $this onPostEdit($script)
+ * @method $this onPostRemove($script)
+ * @method $this onPostSubmit($script)
+ * @method $this onPostUpload($script)
+ * @method $this onPreBlur($script)
+ * @method $this onPreBlurCancelled($script)
+ * @method $this onPreClose($script)
+ * @method $this onPreCreate($script)
+ * @method $this onPreEdit($script)
+ * @method $this onPreOpen($script)
+ * @method $this onPreOpenCancelled($script)
+ * @method $this onPreRemove($script)
+ * @method $this onPreSubmit($script)
+ * @method $this onPreSubmitCancelled($script)
+ * @method $this onPreUpload($script)
+ * @method $this onPreUploadCancelled($script)
+ * @method $this onProcessing($script)
+ * @method $this onRemove($script)
+ * @method $this onSetData($script)
+ * @method $this onSubmitComplete($script)
+ * @method $this onSubmitError($script)
+ * @method $this onSubmitSuccess($script)
+ * @method $this onSubmitUnsuccessful($script)
+ * @method $this onUploadXhrError($script)
+ * @method $this onUploadXhrSuccess($script)
*/
trait HasEvents
{
/**
* Magic method handler for editor events.
*
- * @param string $name
- * @param mixed $arguments
+ * @param string $method
+ * @param array{0: string} $parameters
* @return $this
*/
- public function __call($name, $arguments)
+ public function __call($method, $parameters)
{
- if (Str::startsWith($name, 'on')) {
- $event = Str::camel(substr($name, 2, strlen($name) - 2));
+ if (Str::startsWith($method, 'on')) {
+ $event = Str::camel(substr($method, 2, strlen($method) - 2));
- return $this->on($event, $arguments[0]);
+ return $this->on($event, $parameters[0]);
}
- return parent::__call($name, $arguments);
+ return parent::__call($method, $parameters);
}
/**
* Add Editor event listener scripts.
*
- * @param string $event
- * @param string $script
* @return $this
+ *
* @see https://editor.datatables.net/reference/event
*/
- public function on($event, $script)
+ public function on(string $event, mixed $script): static
{
- $this->attributes['events'][] = [
+ $this->events[] = [
'event' => $event,
'script' => value($script),
];
diff --git a/src/Html/Enums/LayoutPosition.php b/src/Html/Enums/LayoutPosition.php
new file mode 100644
index 0000000..9865d04
--- /dev/null
+++ b/src/Html/Enums/LayoutPosition.php
@@ -0,0 +1,28 @@
+ 0) {
+ $parts = Str::of($this->value)->ucsplit();
+
+ return $parts->shift().$order.$parts->first();
+ }
+
+ return $this->value;
+ }
+}
diff --git a/src/Html/Fluent.php b/src/Html/Fluent.php
new file mode 100644
index 0000000..2ff5837
--- /dev/null
+++ b/src/Html/Fluent.php
@@ -0,0 +1,235 @@
+
+ * @implements \ArrayAccess
+ */
+class Fluent implements Arrayable, ArrayAccess, Jsonable, JsonSerializable
+{
+ /**
+ * All of the attributes set on the fluent instance.
+ *
+ * @var array
+ */
+ protected $attributes = [];
+
+ /**
+ * Create a new fluent instance.
+ *
+ * @param iterable $attributes
+ * @return void
+ */
+ public function __construct($attributes = [])
+ {
+ foreach ($attributes as $key => $value) {
+ $this->attributes[$key] = $value;
+ }
+ }
+
+ /**
+ * Get an attribute from the fluent instance using "dot" notation.
+ *
+ * @template TGetDefault
+ *
+ * @param TKey $key
+ * @param TGetDefault|(\Closure(): TGetDefault) $default
+ * @return TValue|TGetDefault
+ */
+ public function get($key, $default = null)
+ {
+ return data_get($this->attributes, $key, $default);
+ }
+
+ /**
+ * Get an attribute from the fluent instance.
+ *
+ * @param string $key
+ * @param mixed $default
+ * @return mixed
+ */
+ public function value($key, $default = null)
+ {
+ if (array_key_exists($key, $this->attributes)) {
+ return $this->attributes[$key];
+ }
+
+ return value($default);
+ }
+
+ /**
+ * Get the value of the given key as a new Fluent instance.
+ *
+ * @param string $key
+ * @param mixed $default
+ * @return static
+ */
+ public function scope($key, $default = null)
+ {
+ return new static(
+ (array) $this->get($key, $default)
+ );
+ }
+
+ /**
+ * Get the attributes from the fluent instance.
+ *
+ * @return array
+ */
+ public function getAttributes()
+ {
+ return $this->attributes;
+ }
+
+ /**
+ * Convert the fluent instance to an array.
+ *
+ * @return array
+ */
+ public function toArray()
+ {
+ return $this->attributes;
+ }
+
+ /**
+ * Convert the fluent instance to a Collection.
+ *
+ * @param string|null $key
+ * @return \Illuminate\Support\Collection
+ */
+ public function collect($key = null)
+ {
+ return new Collection($this->get($key));
+ }
+
+ /**
+ * Convert the object into something JSON serializable.
+ *
+ * @return array
+ */
+ public function jsonSerialize(): array
+ {
+ return $this->toArray();
+ }
+
+ /**
+ * Convert the fluent instance to JSON.
+ *
+ * @param int $options
+ * @return string
+ */
+ public function toJson($options = 0)
+ {
+ return json_encode($this->jsonSerialize(), $options);
+ }
+
+ /**
+ * Determine if the given offset exists.
+ *
+ * @param TKey $offset
+ */
+ public function offsetExists($offset): bool
+ {
+ return isset($this->attributes[$offset]);
+ }
+
+ /**
+ * Get the value for a given offset.
+ *
+ * @param TKey $offset
+ * @return TValue|null
+ */
+ public function offsetGet($offset): mixed
+ {
+ return $this->value($offset);
+ }
+
+ /**
+ * Set the value at the given offset.
+ *
+ * @param TKey $offset
+ * @param TValue $value
+ */
+ public function offsetSet($offset, $value): void
+ {
+ $this->attributes[$offset] = $value;
+ }
+
+ /**
+ * Unset the value at the given offset.
+ *
+ * @param TKey $offset
+ */
+ public function offsetUnset($offset): void
+ {
+ unset($this->attributes[$offset]);
+ }
+
+ /**
+ * Handle dynamic calls to the fluent instance to set attributes.
+ *
+ * @param TKey $method
+ * @param array{0: ?TValue} $parameters
+ * @return $this
+ */
+ public function __call($method, $parameters)
+ {
+ $this->attributes[$method] = count($parameters) > 0 ? reset($parameters) : true;
+
+ return $this;
+ }
+
+ /**
+ * Dynamically retrieve the value of an attribute.
+ *
+ * @param TKey $key
+ * @return TValue|null
+ */
+ public function __get($key)
+ {
+ return $this->value($key);
+ }
+
+ /**
+ * Dynamically set the value of an attribute.
+ *
+ * @param TKey $key
+ * @param TValue $value
+ * @return void
+ */
+ public function __set($key, $value)
+ {
+ $this->offsetSet($key, $value);
+ }
+
+ /**
+ * Dynamically check if an attribute is set.
+ *
+ * @param TKey $key
+ * @return bool
+ */
+ public function __isset($key)
+ {
+ return $this->offsetExists($key);
+ }
+
+ /**
+ * Dynamically unset an attribute.
+ *
+ * @param TKey $key
+ * @return void
+ */
+ public function __unset($key)
+ {
+ $this->offsetUnset($key);
+ }
+}
diff --git a/src/Html/HasAuthorizations.php b/src/Html/HasAuthorizations.php
index b93f445..17af1db 100644
--- a/src/Html/HasAuthorizations.php
+++ b/src/Html/HasAuthorizations.php
@@ -8,42 +8,45 @@ trait HasAuthorizations
{
/**
* Flag to check if user is authorized to use the button.
- *
- * @var bool
*/
- protected $authorized = true;
+ protected bool $authorized = true;
/**
* Make a button if condition is true.
- *
- * @param bool|callable $condition
- * @param string|array $options
- * @return static
*/
- public static function makeIf($condition, $options = [])
+ public static function makeIf(callable|bool $condition, array|string $options = []): static
{
- if (value($condition)) {
+ if (is_callable($condition)) {
+ $condition = value($condition);
+ }
+
+ if ($condition === true) {
return static::make($options);
}
- return static::make([])->authorized(false);
+ return app(static::class)->authorized(false);
+ }
+
+ /**
+ * Set authorization status of the button.
+ */
+ public function authorized(callable|bool $bool): static
+ {
+ $this->authorized = (bool) value($bool);
+
+ return $this;
}
/**
* Make a button if the user is authorized.
- *
- * @param string $permission
- * @param string|array $options
- * @param Authorizable|null $user
- * @return static
*/
- public static function makeIfCan($permission, $options = [], Authorizable $user = null)
+ public static function makeIfCan(string $permission, array|string $options = [], ?Authorizable $user = null): static
{
if (is_null($user)) {
$user = auth()->user();
}
- if ($user->can($permission)) {
+ if ($user instanceof Authorizable && $user->can($permission)) {
return static::make($options);
}
@@ -52,49 +55,40 @@ public static function makeIfCan($permission, $options = [], Authorizable $user
/**
* Make a button if the user is not authorized.
- *
- * @param string $permission
- * @param string|array $options
- * @param Authorizable|null $user
- * @return static
*/
- public static function makeIfCannot($permission, $options = [], Authorizable $user = null)
- {
+ public static function makeIfCannot(
+ string $permission,
+ array|string $options = [],
+ ?Authorizable $user = null
+ ): static {
if (is_null($user)) {
$user = auth()->user();
}
- if (! $user->can($permission)) {
+ if ($user instanceof Authorizable && ! $user->can($permission)) {
return static::make($options);
}
- return static::make([])->authorized(false);
+ return app(static::class)->authorized(false);
}
/**
- * Set authorization status of the button.
- *
- * @param bool|callable $bool
- * @return static
+ * Convert the Fluent instance to an array.
*/
- public function authorized($bool)
+ public function toArray(): array
{
- $this->authorized = value($bool);
+ if (! $this->isAuthorized()) {
+ return [];
+ }
- return $this;
+ return parent::toArray();
}
/**
- * Convert the Fluent instance to an array.
- *
- * @return array
+ * Check if instance is authorized
*/
- public function toArray()
+ public function isAuthorized(): bool
{
- if ($this->authorized) {
- return parent::toArray();
- }
-
- return [];
+ return $this->authorized;
}
}
diff --git a/src/Html/HasEditor.php b/src/Html/HasEditor.php
index 4b76cfe..5726a15 100644
--- a/src/Html/HasEditor.php
+++ b/src/Html/HasEditor.php
@@ -8,27 +8,31 @@ trait HasEditor
{
/**
* Collection of Editors.
- *
- * @var null|Editor
*/
- protected $editors = [];
+ protected array $editors = [];
/**
* Attach multiple editors to builder.
*
- * @param array|mixed ...$editors
+ * @param array|mixed ...$editors
* @return $this
+ *
* @see https://editor.datatables.net/
- * @throws \Exception
*/
- public function editors(...$editors)
+ public function editors(...$editors): static
{
if (is_array($editors[0])) {
$editors = $editors[0];
}
+ $this->editors = [];
+
foreach ($editors as $editor) {
- $this->editor($editor);
+ if ($editor instanceof Editor) {
+ $this->editor($editor);
+ } else {
+ $this->editor(new Editor($editor));
+ }
}
return $this;
@@ -37,51 +41,31 @@ public function editors(...$editors)
/**
* Integrate with DataTables Editor.
*
- * @param array|Editor $fields
* @return $this
+ *
* @see https://editor.datatables.net/
- * @throws \Exception
*/
- public function editor($fields)
+ public function editor(Editor $editor): static
{
- $this->setTemplate($this->config->get('datatables-html.editor', 'datatables::editor'));
-
- $editor = $this->newEditor($fields);
+ /** @var string $template */
+ $template = $this->config->get('datatables-html.editor', 'datatables::editor');
- $this->editors[] = $editor;
-
- return $this;
- }
-
- /**
- * @param array|Editor $fields
- * @return array|Editor
- * @throws \Exception
- */
- protected function newEditor($fields)
- {
- if ($fields instanceof Editor) {
- $editor = $fields;
- } else {
- $editor = new Editor;
- $editor->fields($fields);
- }
+ $this->setTemplate($template);
if (! $editor->table) {
- $editor->table('#' . $this->getTableAttribute('id'));
+ $editor->table('#'.$this->getTableAttribute('id'));
}
if (! $editor->ajax) {
$editor->ajax($this->getAjaxUrl());
}
- return $editor;
+ $this->editors[] = $editor;
+
+ return $this;
}
- /**
- * @return array|null
- */
- public function getEditors()
+ public function getEditors(): array
{
return $this->editors;
}
diff --git a/src/Html/HasOptions.php b/src/Html/HasOptions.php
index ce95441..14fcd6d 100644
--- a/src/Html/HasOptions.php
+++ b/src/Html/HasOptions.php
@@ -2,8 +2,6 @@
namespace Yajra\DataTables\Html;
-use Yajra\DataTables\Html\Options;
-
/**
* DataTables - Options builder.
*
@@ -11,10 +9,10 @@
*/
trait HasOptions
{
- use Options\HasFeatures;
- use Options\HasData;
+ use Options\HasAjax;
use Options\HasCallbacks;
use Options\HasColumns;
+ use Options\HasFeatures;
use Options\HasInternationalisation;
use Options\Plugins\AutoFill;
use Options\Plugins\Buttons;
@@ -26,17 +24,17 @@ trait HasOptions
use Options\Plugins\RowGroup;
use Options\Plugins\RowReorder;
use Options\Plugins\Scroller;
- use Options\Plugins\Select;
use Options\Plugins\SearchPanes;
+ use Options\Plugins\Select;
/**
* Set deferLoading option value.
*
- * @param mixed $value
* @return $this
+ *
* @see https://datatables.net/reference/option/deferLoading
*/
- public function deferLoading($value = null)
+ public function deferLoading(array|int|null $value = null): static
{
$this->attributes['deferLoading'] = $value;
@@ -46,11 +44,11 @@ public function deferLoading($value = null)
/**
* Set destroy option value.
*
- * @param bool $value
* @return $this
+ *
* @see https://datatables.net/reference/option/destroy
*/
- public function destroy(bool $value = false)
+ public function destroy(bool $value = false): static
{
$this->attributes['destroy'] = $value;
@@ -60,11 +58,11 @@ public function destroy(bool $value = false)
/**
* Set displayStart option value.
*
- * @param int $value
* @return $this
+ *
* @see https://datatables.net/reference/option/displayStart
*/
- public function displayStart(int $value = 0)
+ public function displayStart(int $value = 0): static
{
$this->attributes['displayStart'] = $value;
@@ -74,25 +72,50 @@ public function displayStart(int $value = 0)
/**
* Set dom option value.
*
- * @param string $value
* @return $this
+ *
+ * @deprecated Use layout() method instead.
* @see https://datatables.net/reference/option/dom
*/
- public function dom(string $value)
+ public function dom(string $value): static
{
$this->attributes['dom'] = $value;
return $this;
}
+ /**
+ * Set layout option value.
+ *
+ * @return $this
+ *
+ * @see https://datatables.net/reference/option/layout
+ */
+ public function layout(array|Layout|callable $value): static
+ {
+ if ($value instanceof Layout) {
+ $value = $value->toArray();
+ }
+
+ if (is_callable($value)) {
+ $layout = new Layout;
+ $value($layout);
+ $value = $layout->toArray();
+ }
+
+ $this->attributes['layout'] = $value;
+
+ return $this;
+ }
+
/**
* Set lengthMenu option value.
*
- * @param array $value
* @return $this
+ *
* @see https://datatables.net/reference/option/lengthMenu
*/
- public function lengthMenu(array $value = [10, 25, 50, 100])
+ public function lengthMenu(array $value = [10, 25, 50, 100]): static
{
$this->attributes['lengthMenu'] = $value;
@@ -102,11 +125,11 @@ public function lengthMenu(array $value = [10, 25, 50, 100])
/**
* Set orders option value.
*
- * @param array $value
* @return $this
+ *
* @see https://datatables.net/reference/option/order
*/
- public function orders(array $value)
+ public function orders(array $value): static
{
$this->attributes['order'] = $value;
@@ -116,11 +139,11 @@ public function orders(array $value)
/**
* Set orderCellsTop option value.
*
- * @param bool $value
* @return $this
+ *
* @see https://datatables.net/reference/option/orderCellsTop
*/
- public function orderCellsTop(bool $value = false)
+ public function orderCellsTop(bool $value = false): static
{
$this->attributes['orderCellsTop'] = $value;
@@ -130,11 +153,11 @@ public function orderCellsTop(bool $value = false)
/**
* Set orderClasses option value.
*
- * @param bool $value
* @return $this
+ *
* @see https://datatables.net/reference/option/orderClasses
*/
- public function orderClasses(bool $value = true)
+ public function orderClasses(bool $value = true): static
{
$this->attributes['orderClasses'] = $value;
@@ -144,12 +167,11 @@ public function orderClasses(bool $value = true)
/**
* Order option builder.
*
- * @param int|array $index
- * @param string $direction
* @return $this
+ *
* @see https://datatables.net/reference/option/order
*/
- public function orderBy($index, $direction = 'desc')
+ public function orderBy(array|int $index, string $direction = 'desc'): static
{
if ($direction != 'desc') {
$direction = 'asc';
@@ -167,12 +189,11 @@ public function orderBy($index, $direction = 'desc')
/**
* Order Fixed option builder.
*
- * @param int|array $index
- * @param string $direction
* @return $this
+ *
* @see https://datatables.net/reference/option/orderFixed
*/
- public function orderByFixed($index, $direction = 'desc')
+ public function orderByFixed(array|int $index, string $direction = 'desc'): static
{
if ($direction != 'desc') {
$direction = 'asc';
@@ -190,11 +211,11 @@ public function orderByFixed($index, $direction = 'desc')
/**
* Set orderMulti option value.
*
- * @param bool $value
* @return $this
+ *
* @see https://datatables.net/reference/option/orderMulti
*/
- public function orderMulti(bool $value = true)
+ public function orderMulti(bool $value = true): static
{
$this->attributes['orderMulti'] = $value;
@@ -204,11 +225,11 @@ public function orderMulti(bool $value = true)
/**
* Set pageLength option value.
*
- * @param int $value
* @return $this
+ *
* @see https://datatables.net/reference/option/pageLength
*/
- public function pageLength(int $value = 10)
+ public function pageLength(int $value = 10): static
{
$this->attributes['pageLength'] = $value;
@@ -218,11 +239,11 @@ public function pageLength(int $value = 10)
/**
* Set pagingType option value.
*
- * @param string $value
* @return $this
+ *
* @see https://datatables.net/reference/option/pagingType
*/
- public function pagingType(string $value = 'simple_numbers')
+ public function pagingType(string $value = 'simple_numbers'): static
{
$this->attributes['pagingType'] = $value;
@@ -232,11 +253,11 @@ public function pagingType(string $value = 'simple_numbers')
/**
* Set renderer option value.
*
- * @param mixed $value
* @return $this
+ *
* @see https://datatables.net/reference/option/renderer
*/
- public function renderer($value = 'bootstrap')
+ public function renderer(string $value = 'bootstrap'): static
{
$this->attributes['renderer'] = $value;
@@ -246,11 +267,11 @@ public function renderer($value = 'bootstrap')
/**
* Set retrieve option value.
*
- * @param bool $value
* @return $this
+ *
* @see https://datatables.net/reference/option/retrieve
*/
- public function retrieve(bool $value = false)
+ public function retrieve(bool $value = false): static
{
$this->attributes['retrieve'] = $value;
@@ -260,11 +281,11 @@ public function retrieve(bool $value = false)
/**
* Set rowId option value.
*
- * @param string $value
* @return $this
+ *
* @see https://datatables.net/reference/option/rowId
*/
- public function rowId(string $value = 'DT_RowId')
+ public function rowId(string $value = 'DT_RowId'): static
{
$this->attributes['rowId'] = $value;
@@ -274,11 +295,11 @@ public function rowId(string $value = 'DT_RowId')
/**
* Set scrollCollapse option value.
*
- * @param mixed $value
* @return $this
+ *
* @see https://datatables.net/reference/option/scrollCollapse
*/
- public function scrollCollapse($value = false)
+ public function scrollCollapse(bool $value = false): static
{
$this->attributes['scrollCollapse'] = $value;
@@ -288,11 +309,11 @@ public function scrollCollapse($value = false)
/**
* Set search option value.
*
- * @param array $value
* @return $this
+ *
* @see https://datatables.net/reference/option/search
*/
- public function search(array $value)
+ public function search(array $value): static
{
$this->attributes['search'] = $value;
@@ -302,11 +323,11 @@ public function search(array $value)
/**
* Set searchCols option value.
*
- * @param array $value
* @return $this
+ *
* @see https://datatables.net/reference/option/searchCols
*/
- public function searchCols(array $value)
+ public function searchCols(array $value): static
{
$this->attributes['searchCols'] = $value;
@@ -316,11 +337,11 @@ public function searchCols(array $value)
/**
* Set searchDelay option value.
*
- * @param int $value
* @return $this
+ *
* @see https://datatables.net/reference/option/searchDelay
*/
- public function searchDelay(int $value)
+ public function searchDelay(int $value): static
{
$this->attributes['searchDelay'] = $value;
@@ -330,11 +351,11 @@ public function searchDelay(int $value)
/**
* Set stateDuration option value.
*
- * @param int $value
* @return $this
+ *
* @see https://datatables.net/reference/option/stateDuration
*/
- public function stateDuration(int $value)
+ public function stateDuration(int $value): static
{
$this->attributes['stateDuration'] = $value;
@@ -344,11 +365,11 @@ public function stateDuration(int $value)
/**
* Set stripeClasses option value.
*
- * @param array $value
* @return $this
+ *
* @see https://datatables.net/reference/option/stripeClasses
*/
- public function stripeClasses(array $value)
+ public function stripeClasses(array $value): static
{
$this->attributes['stripeClasses'] = $value;
@@ -358,14 +379,37 @@ public function stripeClasses(array $value)
/**
* Set tabIndex option value.
*
- * @param int $value
* @return $this
+ *
* @see https://datatables.net/reference/option/tabIndex
*/
- public function tabIndex(int $value = 0)
+ public function tabIndex(int $value = 0): static
{
$this->attributes['tabIndex'] = $value;
return $this;
}
+
+ /**
+ * @return $this
+ */
+ public function setPluginAttribute(string $key, array|bool $value): static
+ {
+ if (is_array($value)) {
+ $this->attributes[$key] = array_merge((array) ($this->attributes[$key] ?? []), $value);
+ } else {
+ $this->attributes[$key] = $value;
+ }
+
+ return $this;
+ }
+
+ public function getPluginAttribute(string $plugin, ?string $key = null): mixed
+ {
+ if (is_null($key)) {
+ return $this->attributes[$plugin] ?? true;
+ }
+
+ return $this->attributes[$plugin][$key] ?? false;
+ }
}
diff --git a/src/Html/HasTable.php b/src/Html/HasTable.php
index 67b85db..aa6c4bb 100644
--- a/src/Html/HasTable.php
+++ b/src/Html/HasTable.php
@@ -6,28 +6,12 @@
trait HasTable
{
- /**
- * Retrieves HTML table attribute value.
- *
- * @param string $attribute
- * @return mixed
- * @throws \Exception
- */
- public function getTableAttribute($attribute)
- {
- if (! array_key_exists($attribute, $this->tableAttributes)) {
- throw new \Exception("Table attribute '{$attribute}' does not exist.");
- }
-
- return $this->tableAttributes[$attribute];
- }
+ protected ?string $theadClass = null;
/**
* Get table computed table attributes.
- *
- * @return array
*/
- public function getTableAttributes()
+ public function getTableAttributes(): array
{
return $this->tableAttributes;
}
@@ -35,32 +19,19 @@ public function getTableAttributes()
/**
* Sets HTML table "id" attribute.
*
- * @param string $id
* @return $this
*/
- public function setTableId($id)
+ public function setTableId(string $id): static
{
return $this->setTableAttribute('id', $id);
}
- /**
- * Get HTML table "id" attribute.
- *
- * @return string
- */
- public function getTableId()
- {
- return $this->getTableAttribute('id');
- }
-
/**
* Sets HTML table attribute(s).
*
- * @param string|array $attribute
- * @param mixed $value
* @return $this
*/
- public function setTableAttribute($attribute, $value = null)
+ public function setTableAttribute(array|string $attribute, ?string $value = null): static
{
if (is_array($attribute)) {
return $this->setTableAttributes($attribute);
@@ -74,10 +45,9 @@ public function setTableAttribute($attribute, $value = null)
/**
* Sets multiple HTML table attributes at once.
*
- * @param array $attributes
* @return $this
*/
- public function setTableAttributes(array $attributes)
+ public function setTableAttributes(array $attributes): static
{
foreach ($attributes as $attribute => $value) {
$this->tableAttributes[$attribute] = $value;
@@ -86,37 +56,63 @@ public function setTableAttributes(array $attributes)
return $this;
}
+ /**
+ * Get HTML table "id" attribute.
+ */
+ public function getTableId(): string
+ {
+ return $this->getTableAttribute('id');
+ }
+
+ /**
+ * Retrieves HTML table attribute value.
+ */
+ public function getTableAttribute(string $attribute): string
+ {
+ return $this->tableAttributes[$attribute] ?? '';
+ }
+
/**
* Add class names to the "class" attribute of HTML table.
*
- * @param string|array $class
* @return $this
*/
- public function addTableClass($class)
+ public function addTableClass(array|string $class): static
{
$class = is_array($class) ? implode(' ', $class) : $class;
$currentClass = Arr::get(array_change_key_case($this->tableAttributes), 'class');
- $classes = preg_split('#\s+#', $currentClass . ' ' . $class, null, PREG_SPLIT_NO_EMPTY);
- $class = implode(' ', array_unique($classes));
+ $classes = preg_split('#\s+#', $currentClass.' '.$class, -1, PREG_SPLIT_NO_EMPTY);
+ $class = implode(' ', array_unique((array) $classes));
return $this->setTableAttribute('class', $class);
}
+ /**
+ * Set table > thead class names.
+ *
+ * @return $this
+ */
+ public function setTableHeadClass(string $class): static
+ {
+ $this->theadClass = " class=\"$class\"";
+
+ return $this;
+ }
+
/**
* Remove class names from the "class" attribute of HTML table.
*
- * @param string|array $class
* @return $this
*/
- public function removeTableClass($class)
+ public function removeTableClass(array|string $class): static
{
$class = is_array($class) ? implode(' ', $class) : $class;
- $currentClass = Arr::get(array_change_key_case($this->tableAttributes), 'class');
+ $currentClass = $this->getTableAttribute('class');
$classes = array_diff(
- preg_split('#\s+#', $currentClass, null, PREG_SPLIT_NO_EMPTY),
- preg_split('#\s+#', $class, null, PREG_SPLIT_NO_EMPTY)
+ (array) preg_split('#\s+#', (string) $currentClass, -1, PREG_SPLIT_NO_EMPTY),
+ (array) preg_split('#\s+#', $class, -1, PREG_SPLIT_NO_EMPTY)
);
$class = implode(' ', array_unique($classes));
@@ -125,57 +121,64 @@ public function removeTableClass($class)
/**
* Compile table headers and to support responsive extension.
- *
- * @return array
*/
- protected function compileTableHeaders()
+ protected function compileTableHeaders(): array
{
$th = [];
- foreach ($this->collection->toArray() as $row) {
- $thAttr = $this->html->attributes(array_merge(
- Arr::only($row, ['class', 'id', 'title', 'width', 'style', 'data-class', 'data-hide']),
- $row['attributes'],
- isset($row['titleAttr']) ? ['title' => $row['titleAttr']] : []
- ));
- $th[] = '' . $row['title'] . ' | ';
- }
+
+ $this->collection->each(function (Column $column) use (&$th) {
+ $only = Arr::only(
+ $column->toArray(),
+ ['class', 'id', 'title', 'width', 'style', 'data-class', 'data-hide']
+ );
+
+ $attributes = array_merge(
+ $only,
+ $column->attributes,
+ isset($column['titleAttr']) ? ['title' => $column['titleAttr']] : []
+ );
+
+ $thAttr = $this->html->attributes($attributes);
+ $th[] = ''.$column['title'].' | ';
+ });
return $th;
}
/**
* Compile table search headers.
- *
- * @return array
*/
- protected function compileTableSearchHeaders()
+ protected function compileTableSearchHeaders(): array
{
$search = [];
- foreach ($this->collection->all() as $key => $row) {
- $search[] = $row['searchable'] ? '' . (isset($row->search) ? $row->search : '') . ' | ' : ' | ';
- }
+
+ $this->collection->each(function (Column $column) use (&$search) {
+ $search[] = $column['searchable'] ? ''.($column['search'] ?? '').' | ' : ' | ';
+ });
return $search;
}
/**
* Compile table footer contents.
- *
- * @return array
*/
- protected function compileTableFooter()
+ protected function compileTableFooter(): array
{
$footer = [];
- foreach ($this->collection->all() as $row) {
- if (is_array($row->footer)) {
- $footerAttr = $this->html->attributes(Arr::only($row->footer,
- ['class', 'id', 'title', 'width', 'style', 'data-class', 'data-hide']));
- $title = isset($row->footer['title']) ? $row->footer['title'] : '';
- $footer[] = '' . $title . ' | ';
+
+ $this->collection->each(function (Column $column) use (&$footer) {
+ if (is_array($column->footer)) {
+ $footerAttr = $this->html->attributes(
+ Arr::only($column->footer, ['class', 'id', 'title', 'width', 'style', 'data-class', 'data-hide'])
+ );
+
+ $title = $column->footer['title'] ?? '';
+
+ $footer[] = ''.$title.' | ';
} else {
- $footer[] = '' . $row->footer . ' | ';
+ $footer[] = ''.$column->footer.' | ';
}
- }
+ });
return $footer;
}
diff --git a/src/Html/HtmlBuilder.php b/src/Html/HtmlBuilder.php
new file mode 100644
index 0000000..cf02734
--- /dev/null
+++ b/src/Html/HtmlBuilder.php
@@ -0,0 +1,436 @@
+url->asset($url, $secure);
+
+ return $this->toHtmlString('');
+ }
+
+ /**
+ * Transform the string to an Html serializable object
+ */
+ protected function toHtmlString(string $html): HtmlString
+ {
+ return new HtmlString($html);
+ }
+
+ /**
+ * Build an HTML attribute string from an array.
+ */
+ public function attributes(array $attributes): string
+ {
+ $html = [];
+
+ foreach ($attributes as $key => $value) {
+ $element = $this->attributeElement($key, $value);
+
+ if (! is_null($element)) {
+ $html[] = $element;
+ }
+ }
+
+ return ! empty($html) ? ' '.implode(' ', $html) : '';
+ }
+
+ /**
+ * Build a single attribute element.
+ */
+ protected function attributeElement(string $key, mixed $value): mixed
+ {
+ // For numeric keys we will assume that the value is a boolean attribute
+ // where the presence of the attribute represents a true value and the
+ // absence represents a false value.
+ // This will convert HTML attributes such as "required" to a correct
+ // form instead of using incorrect numerics.
+ if (is_numeric($key)) {
+ return $value;
+ }
+
+ // Treat boolean attributes as HTML properties
+ if (is_bool($value) && $key !== 'value') {
+ return $value ? $key : '';
+ }
+
+ if (is_array($value) && $key === 'class') {
+ return 'class="'.implode(' ', $value).'"';
+ }
+
+ if (is_bool($value) || is_float($value) || is_int($value) || is_resource($value) || is_string($value)) {
+ return $key.'="'.e(strval($value), false).'"';
+ }
+
+ return null;
+ }
+
+ /**
+ * Generate a link to a CSS file.
+ */
+ public function style(string $url, array $attributes = [], ?bool $secure = null): HtmlString
+ {
+ $defaults = ['media' => 'all', 'type' => 'text/css', 'rel' => 'stylesheet'];
+
+ $attributes = array_merge($defaults, $attributes);
+
+ $attributes['href'] = $this->url->asset($url, $secure);
+
+ return $this->toHtmlString('attributes($attributes).'>');
+ }
+
+ /**
+ * Generate an HTML image element.
+ */
+ public function image(string $url, ?string $alt = null, array $attributes = [], ?bool $secure = null): HtmlString
+ {
+ $attributes['alt'] = $alt;
+
+ return $this->toHtmlString('
attributes($attributes).'>');
+ }
+
+ /**
+ * Generate a link to a Favicon file.
+ */
+ public function favicon(string $url, array $attributes = [], ?bool $secure = null): HtmlString
+ {
+ $defaults = ['rel' => 'shortcut icon', 'type' => 'image/x-icon'];
+
+ $attributes = array_merge($defaults, $attributes);
+
+ $attributes['href'] = $this->url->asset($url, $secure);
+
+ return $this->toHtmlString('attributes($attributes).'>');
+ }
+
+ /**
+ * Generate a HTTPS HTML link.
+ */
+ public function secureLink(
+ string $url,
+ ?string $title = null,
+ array $attributes = [],
+ bool $escape = true
+ ): HtmlString {
+ return $this->link($url, $title, $attributes, true, $escape);
+ }
+
+ /**
+ * Generate a HTML link.
+ */
+ public function link(
+ string $url,
+ ?string $title = null,
+ array $attributes = [],
+ ?bool $secure = null,
+ bool $escape = true
+ ): HtmlString {
+ $url = $this->url->to($url, [], $secure);
+
+ if (is_null($title)) {
+ $title = $url;
+ }
+
+ if ($escape) {
+ $title = $this->entities($title);
+ }
+
+ return $this->toHtmlString(
+ 'attributes($attributes).'>'.$title.''
+ );
+ }
+
+ /**
+ * Convert an HTML string to entities.
+ */
+ public function entities(string $value): string
+ {
+ return htmlentities($value, ENT_QUOTES, 'UTF-8', false);
+ }
+
+ /**
+ * Generate a HTTPS HTML link to an asset.
+ */
+ public function linkSecureAsset(
+ string $url,
+ ?string $title = null,
+ array $attributes = [],
+ bool $escape = true
+ ): HtmlString {
+ return $this->linkAsset($url, $title, $attributes, true, $escape);
+ }
+
+ /**
+ * Generate a HTML link to an asset.
+ */
+ public function linkAsset(
+ string $url,
+ ?string $title = null,
+ array $attributes = [],
+ ?bool $secure = null,
+ bool $escape = true
+ ): HtmlString {
+ $url = $this->url->asset($url, $secure);
+
+ return $this->link($url, $title ?: $url, $attributes, $secure, $escape);
+ }
+
+ /**
+ * Generate a HTML link to a named route.
+ */
+ public function linkRoute(
+ string $name,
+ ?string $title = null,
+ array $parameters = [],
+ array $attributes = [],
+ ?bool $secure = null,
+ bool $escape = true
+ ): HtmlString {
+ return $this->link($this->url->route($name, $parameters), $title, $attributes, $secure, $escape);
+ }
+
+ /**
+ * Generate a HTML link to a controller action.
+ */
+ public function linkAction(
+ string $action,
+ ?string $title = null,
+ array $parameters = [],
+ array $attributes = [],
+ ?bool $secure = null,
+ bool $escape = true
+ ): HtmlString {
+ return $this->link($this->url->action($action, $parameters), $title, $attributes, $secure, $escape);
+ }
+
+ /**
+ * Generate a HTML link to an email address.
+ */
+ public function mailto(string $email, ?string $title = null, array $attributes = [], bool $escape = true): HtmlString
+ {
+ $email = $this->email($email);
+
+ $title = $title ?: $email;
+
+ if ($escape) {
+ $title = $this->entities($title);
+ }
+
+ $email = $this->obfuscate('mailto:').$email;
+
+ return $this->toHtmlString('attributes($attributes).'>'.$title.'');
+ }
+
+ /**
+ * Obfuscate an e-mail address to prevent spam-bots from sniffing it.
+ */
+ public function email(string $email): string
+ {
+ return str_replace('@', '@', $this->obfuscate($email));
+ }
+
+ /**
+ * Obfuscate a string to prevent spam-bots from sniffing it.
+ *
+ * @throws \Exception
+ */
+ public function obfuscate(string $value): string
+ {
+ $safe = '';
+
+ foreach (str_split($value) as $letter) {
+ if (ord($letter) > 128) {
+ return $letter;
+ }
+
+ // To properly obfuscate the value, we will randomly convert each letter to
+ // its entity or hexadecimal representation, keeping a bot from sniffing
+ // the randomly obfuscated letters out of the string on the responses.
+ switch (random_int(1, 3)) {
+ case 1:
+ $safe .= ''.ord($letter).';';
+ break;
+
+ case 2:
+ $safe .= ''.dechex(ord($letter)).';';
+ break;
+
+ case 3:
+ $safe .= $letter;
+ }
+ }
+
+ return $safe;
+ }
+
+ /**
+ * Generates non-breaking space entities based on number supplied.
+ */
+ public function nbsp(int $num = 1): string
+ {
+ return str_repeat(' ', $num);
+ }
+
+ /**
+ * Generate an ordered list of items.
+ */
+ public function ol(array $list, array $attributes = []): HtmlString|string
+ {
+ return $this->listing('ol', $list, $attributes);
+ }
+
+ /**
+ * Create a listing HTML element.
+ */
+ protected function listing(string $type, array $list, array $attributes = []): HtmlString|string
+ {
+ $html = '';
+
+ if (empty($list)) {
+ return $html;
+ }
+
+ // Essentially we will just spin through the list and build the list of the HTML
+ // elements from the array. We will also handled nested lists in case that is
+ // present in the array. Then we will build out the final listing elements.
+ foreach ($list as $key => $value) {
+ $html .= $this->listingElement($key, $type, $value);
+ }
+
+ $attributes = $this->attributes($attributes);
+
+ return $this->toHtmlString("<{$type}{$attributes}>{$html}{$type}>");
+ }
+
+ /**
+ * Create the HTML for a listing element.
+ */
+ protected function listingElement(mixed $key, string $type, mixed $value): HtmlString|string
+ {
+ if (is_array($value)) {
+ return $this->nestedListing($key, $type, $value);
+ } else {
+ if (is_bool($value)
+ || is_float($value)
+ || is_int($value)
+ || is_resource($value)
+ || is_string($value)
+ || is_null($value)
+ ) {
+ return ''.e(strval($value), false).'';
+ }
+ }
+
+ return ''.$value.'';
+ }
+
+ /**
+ * Create the HTML for a nested listing attribute.
+ */
+ protected function nestedListing(mixed $key, string $type, array $value): HtmlString|string
+ {
+ if (is_int($key)) {
+ return $this->listing($type, $value);
+ } else {
+ return ''.$key.$this->listing($type, $value).'';
+ }
+ }
+
+ /**
+ * Generate an un-ordered list of items.
+ */
+ public function ul(array $list, array $attributes = []): HtmlString|string
+ {
+ return $this->listing('ul', $list, $attributes);
+ }
+
+ /**
+ * Generate a description list of items.
+ */
+ public function dl(array $list, array $attributes = []): HtmlString
+ {
+ $attributes = $this->attributes($attributes);
+
+ $html = "";
+
+ foreach ($list as $key => $value) {
+ $value = (array) $value;
+
+ $html .= "- $key
";
+
+ foreach ($value as $v_value) {
+ $html .= "- $v_value
";
+ }
+ }
+
+ $html .= '
';
+
+ return $this->toHtmlString($html);
+ }
+
+ /**
+ * Generate a meta tag.
+ */
+ public function meta(string $name, string $content, array $attributes = []): HtmlString
+ {
+ $defaults = compact('name', 'content');
+
+ $attributes = array_merge($defaults, $attributes);
+
+ return $this->toHtmlString('attributes($attributes).'>');
+ }
+
+ /**
+ * Generate an html tag.
+ */
+ public function tag(string $tag, mixed $content, array $attributes = []): HtmlString
+ {
+ $content = is_array($content) ? implode('', $content) : $content;
+
+ if (is_bool($content)
+ || is_float($content)
+ || is_int($content)
+ || is_resource($content)
+ || is_string($content)
+ || is_null($content)
+ ) {
+ return $this->toHtmlString(
+ '<'.$tag.$this->attributes($attributes).'>'.$this->toHtmlString(strval($content)).''.$tag.'>'
+ );
+ }
+
+ return $this->toHtmlString('<'.$tag.$this->attributes($attributes).'>'.$content.''.$tag.'>');
+ }
+}
diff --git a/src/Html/Layout.php b/src/Html/Layout.php
new file mode 100644
index 0000000..c3a952e
--- /dev/null
+++ b/src/Html/Layout.php
@@ -0,0 +1,149 @@
+attributes[LayoutPosition::Top->withOrder($order)] = $options;
+
+ return $this;
+ }
+
+ public function topStart(string|array|null $options, ?int $order = null): static
+ {
+ $this->attributes[LayoutPosition::TopStart->withOrder($order)] = $options;
+
+ return $this;
+ }
+
+ public function topEnd(string|array|null $options, ?int $order = null): static
+ {
+ $this->attributes[LayoutPosition::TopEnd->withOrder($order)] = $options;
+
+ return $this;
+ }
+
+ public function topView(string $selector, ?int $order = null): static
+ {
+ return $this->top($this->renderCustomElement($selector), $order);
+ }
+
+ public function topStartView(string $selector, ?int $order = null): static
+ {
+ return $this->topStart($this->renderCustomElement($selector), $order);
+ }
+
+ public function topEndView(string $selector, ?int $order = null): static
+ {
+ return $this->topEnd($this->renderCustomElement($selector), $order);
+ }
+
+ public function bottom(array|string|null $options, ?int $order = null): static
+ {
+ $this->attributes[LayoutPosition::Bottom->withOrder($order)] = $options;
+
+ return $this;
+ }
+
+ public function bottomStart(string|array|null $options, ?int $order = null): static
+ {
+ $this->attributes[LayoutPosition::BottomStart->withOrder($order)] = $options;
+
+ return $this;
+ }
+
+ public function bottomEnd(string|array|null $options, ?int $order = null): static
+ {
+ $this->attributes[LayoutPosition::BottomEnd->withOrder($order)] = $options;
+
+ return $this;
+ }
+
+ public function bottomView(string $selector, ?int $order = null): static
+ {
+ return $this->bottom($this->renderCustomElement($selector), $order);
+ }
+
+ public function bottomStartView(string $selector, ?int $order = null): static
+ {
+ return $this->bottomStart($this->renderCustomElement($selector), $order);
+ }
+
+ public function bottomEndView(string $selector, ?int $order = null): static
+ {
+ return $this->bottomEnd($this->renderCustomElement($selector), $order);
+ }
+
+ /**
+ * @throws Throwable
+ */
+ public function addView(
+ Component|Renderable|string $view,
+ LayoutPosition $layoutPosition,
+ ?int $order = null
+ ): static {
+ if ($view instanceof Component) {
+ $view = Blade::renderComponent($view);
+ }
+
+ $html = $view instanceof Renderable ? $view->render() : Blade::render($view);
+
+ $element = json_encode($html);
+
+ if ($element === false) {
+ throw new InvalidArgumentException("Cannot render view [$html] to json.");
+ }
+
+ $this->attributes[$layoutPosition->withOrder($order)] = $this->renderCustomElement($element, false);
+
+ return $this;
+ }
+
+ /**
+ * @param class-string $component
+ *
+ * @throws Throwable
+ */
+ public function addLivewire(
+ string $component,
+ LayoutPosition $layoutPosition,
+ ?int $order = null
+ ): static {
+ $html = json_encode(Livewire::mount($component));
+
+ if ($html === false) {
+ throw new InvalidArgumentException("Cannot render Livewire component [$component] to json.");
+ }
+
+ $this->attributes[$layoutPosition->withOrder($order)] = $this->renderCustomElement($html, false);
+
+ return $this;
+ }
+
+ private function renderCustomElement(string $element, bool $asJsSelector = true): string
+ {
+ $html = $asJsSelector ? "$('{$element}').html()" : $element;
+
+ return "function() { return $html; }";
+ }
+}
diff --git a/src/Html/Options/HasData.php b/src/Html/Options/HasAjax.php
similarity index 50%
rename from src/Html/Options/HasData.php
rename to src/Html/Options/HasAjax.php
index 21e750b..50d8a75 100644
--- a/src/Html/Options/HasData.php
+++ b/src/Html/Options/HasAjax.php
@@ -3,26 +3,39 @@
namespace Yajra\DataTables\Html\Options;
use Illuminate\Support\Arr;
+use Yajra\DataTables\Utilities\Helper;
/**
* DataTables - Data option builder.
*
* @see https://datatables.net/reference/option/
*/
-trait HasData
+trait HasAjax
{
/**
- * @var string|array
+ * Setup "ajax" parameter with POST method.
+ *
+ * @return $this
*/
- protected $ajax = '';
+ public function postAjax(array|string $attributes = ''): static
+ {
+ if (! is_array($attributes)) {
+ $attributes = ['url' => $attributes];
+ }
+
+ unset($attributes['method']);
+ Arr::set($attributes, 'type', 'POST');
+ Arr::set($attributes, 'headers.X-HTTP-Method-Override', 'GET');
+
+ return $this->ajax($attributes);
+ }
/**
* Setup ajax parameter.
*
- * @param string|array $attributes
* @return $this
*/
- public function ajax($attributes = '')
+ public function ajax(array|string $attributes = ''): static
{
$this->ajax = $attributes;
@@ -30,56 +43,91 @@ public function ajax($attributes = '')
}
/**
- * Setup "ajax" parameter with POST method.
- *
- * @param string|array $attributes
* @return $this
*/
- public function postAjax($attributes = '')
+ public function postAjaxWithForm(string $url, string $formSelector): static
{
- if (! is_array($attributes)) {
- $attributes = ['url' => (string) $attributes];
- }
+ $attributes = ['url' => $url];
- unset($attributes['method']);
Arr::set($attributes, 'type', 'POST');
Arr::set($attributes, 'headers.X-HTTP-Method-Override', 'GET');
+ $script = $this->getScriptWithFormSelector($formSelector);
+
+ $attributes['data'] = "function(data) { $script }";
+
return $this->ajax($attributes);
}
+ protected function getScriptWithFormSelector(string $formSelector): string
+ {
+ return << 1) {
+ data[group[0].name] = [];
+ $.each(group, function(i, obj) {
+ data[obj.name].push(obj.value)
+ })
+ } else {
+ data[group[0].name] = group[0].value;
+ }
+});
+CDATA;
+ }
+
/**
* Setup ajax parameter for datatables pipeline plugin.
*
- * @param string $url
- * @param string $pages
* @return $this
+ *
+ * @see https://datatables.net/examples/server_side/pipeline.html
*/
- public function pipeline($url, $pages)
+ public function pipeline(string $url, int $pages = 5): static
{
- $this->ajax = "$.fn.dataTable.pipeline({ url: '{$url}', pages: {$pages} })";
+ return $this->ajax("$.fn.dataTable.pipeline({ url: '$url', pages: $pages })");
+ }
- return $this;
+ /**
+ * Get ajax url.
+ */
+ public function getAjaxUrl(): string
+ {
+ if (is_array($this->ajax)) {
+ return $this->ajax['url'] ?: url()->current();
+ }
+
+ return $this->ajax ?: url()->current();
+ }
+
+ /**
+ * Set ajax url with data added from form.
+ *
+ * @return $this
+ */
+ public function ajaxWithForm(string $url, string $formSelector): static
+ {
+ return $this->minifiedAjax($url, $this->getScriptWithFormSelector($formSelector));
}
/**
* Minify ajax url generated when using get request
* by deleting unnecessary url params.
*
- * @param string $url
- * @param string $script
- * @param array $data
- * @param array $ajaxParameters
* @return $this
*/
- public function minifiedAjax($url = '', $script = null, $data = [], $ajaxParameters = [])
- {
+ public function minifiedAjax(
+ string $url = '',
+ ?string $script = null,
+ array $data = [],
+ array $ajaxParameters = []
+ ): static {
$this->ajax = [];
$appendData = $this->makeDataScript($data);
$this->ajax['url'] = empty($url) ? url()->full() : $url;
$this->ajax['type'] = 'GET';
- if (isset($this->attributes['serverSide']) ? $this->attributes['serverSide'] : true) {
+ if (! isset($this->attributes['serverSide']) || $this->attributes['serverSide']) {
$this->ajax['data'] = 'function(data) {
for (var i = 0, len = data.columns.length; i < len; i++) {
if (!data.columns[i].search.value) delete data.columns[i].search;
@@ -108,35 +156,16 @@ public function minifiedAjax($url = '', $script = null, $data = [], $ajaxParamet
}
/**
- * Get ajax url.
- *
- * @return array|mixed|string
+ * Make a data script to be appended on ajax request of dataTables.
*/
- public function getAjaxUrl()
+ protected function makeDataScript(array $data): string
{
- if (is_array($this->ajax)) {
- return $this->ajax['url'] ?: url()->current();
+ $script = '';
+ foreach ($data as $key => $value) {
+ $dataValue = Helper::isJavascript($value, $key) ? $value : (is_string($value) ? "'$value'" : $value);
+ $script .= PHP_EOL."data.$key = $dataValue;";
}
- return $this->ajax ?: url()->current();
- }
-
- /**
- * Set ajax url with data added from form.
- *
- * @param string $url
- * @param string $formSelector
- * @return $this
- */
- public function ajaxWithForm($url, $formSelector)
- {
- $script = <<minifiedAjax($url, $script);
+ return $script;
}
}
diff --git a/src/Html/Options/HasCallbacks.php b/src/Html/Options/HasCallbacks.php
index 5bb200c..d63d8bc 100644
--- a/src/Html/Options/HasCallbacks.php
+++ b/src/Html/Options/HasCallbacks.php
@@ -12,11 +12,11 @@ trait HasCallbacks
/**
* Set createdRow option value.
*
- * @param mixed $script
* @return $this
+ *
* @see https://datatables.net/reference/option/createdRow
*/
- public function createdRow($script)
+ public function createdRow(string $script): static
{
$this->attributes['createdRow'] = $script;
@@ -26,11 +26,11 @@ public function createdRow($script)
/**
* Set drawCallback option value.
*
- * @param mixed $script
* @return $this
+ *
* @see https://datatables.net/reference/option/drawCallback
*/
- public function drawCallback($script)
+ public function drawCallback(string $script): static
{
$this->attributes['drawCallback'] = $script;
@@ -41,11 +41,11 @@ public function drawCallback($script)
* Set drawCallback option value with Livewire integration.
* Solution as per issue https://github.com/yajra/laravel-datatables/issues/2401.
*
- * @param mixed|null $script
* @return $this
+ *
* @see https://datatables.net/reference/option/drawCallback
*/
- public function drawCallbackWithLivewire($script = null)
+ public function drawCallbackWithLivewire(?string $script = null): static
{
$js = "function(settings) {
if (window.livewire) {
@@ -63,11 +63,11 @@ public function drawCallbackWithLivewire($script = null)
/**
* Set footerCallback option value.
*
- * @param mixed $script
* @return $this
+ *
* @see https://datatables.net/reference/option/footerCallback
*/
- public function footerCallback($script)
+ public function footerCallback(string $script): static
{
$this->attributes['footerCallback'] = $script;
@@ -77,11 +77,11 @@ public function footerCallback($script)
/**
* Set formatNumber option value.
*
- * @param mixed $script
* @return $this
+ *
* @see https://datatables.net/reference/option/formatNumber
*/
- public function formatNumber($script)
+ public function formatNumber(string $script): static
{
$this->attributes['formatNumber'] = $script;
@@ -91,11 +91,11 @@ public function formatNumber($script)
/**
* Set headerCallback option value.
*
- * @param mixed $script
* @return $this
+ *
* @see https://datatables.net/reference/option/headerCallback
*/
- public function headerCallback($script)
+ public function headerCallback(string $script): static
{
$this->attributes['headerCallback'] = $script;
@@ -105,11 +105,11 @@ public function headerCallback($script)
/**
* Set infoCallback option value.
*
- * @param mixed $script
* @return $this
+ *
* @see https://datatables.net/reference/option/infoCallback
*/
- public function infoCallback($script)
+ public function infoCallback(string $script): static
{
$this->attributes['infoCallback'] = $script;
@@ -119,11 +119,11 @@ public function infoCallback($script)
/**
* Set initComplete option value.
*
- * @param mixed $script
* @return $this
+ *
* @see https://datatables.net/reference/option/initComplete
*/
- public function initComplete($script)
+ public function initComplete(string $script): static
{
$this->attributes['initComplete'] = $script;
@@ -133,11 +133,11 @@ public function initComplete($script)
/**
* Set preDrawCallback option value.
*
- * @param mixed $script
* @return $this
+ *
* @see https://datatables.net/reference/option/preDrawCallback
*/
- public function preDrawCallback($script)
+ public function preDrawCallback(string $script): static
{
$this->attributes['preDrawCallback'] = $script;
@@ -147,11 +147,11 @@ public function preDrawCallback($script)
/**
* Set rowCallback option value.
*
- * @param mixed $script
* @return $this
+ *
* @see https://datatables.net/reference/option/rowCallback
*/
- public function rowCallback($script)
+ public function rowCallback(string $script): static
{
$this->attributes['rowCallback'] = $script;
@@ -161,11 +161,11 @@ public function rowCallback($script)
/**
* Set stateLoadCallback option value.
*
- * @param mixed $script
* @return $this
+ *
* @see https://datatables.net/reference/option/stateLoadCallback
*/
- public function stateLoadCallback($script)
+ public function stateLoadCallback(string $script): static
{
$this->attributes['stateLoadCallback'] = $script;
@@ -175,11 +175,11 @@ public function stateLoadCallback($script)
/**
* Set stateLoaded option value.
*
- * @param mixed $script
* @return $this
+ *
* @see https://datatables.net/reference/option/stateLoaded
*/
- public function stateLoaded($script)
+ public function stateLoaded(string $script): static
{
$this->attributes['stateLoaded'] = $script;
@@ -189,11 +189,11 @@ public function stateLoaded($script)
/**
* Set stateLoadParams option value.
*
- * @param mixed $script
* @return $this
+ *
* @see https://datatables.net/reference/option/stateLoadParams
*/
- public function stateLoadParams($script)
+ public function stateLoadParams(string $script): static
{
$this->attributes['stateLoadParams'] = $script;
@@ -203,11 +203,11 @@ public function stateLoadParams($script)
/**
* Set stateSaveCallback option value.
*
- * @param mixed $script
* @return $this
+ *
* @see https://datatables.net/reference/option/stateSaveCallback
*/
- public function stateSaveCallback($script)
+ public function stateSaveCallback(string $script): static
{
$this->attributes['stateSaveCallback'] = $script;
@@ -217,11 +217,11 @@ public function stateSaveCallback($script)
/**
* Set stateSaveParams option value.
*
- * @param mixed $script
* @return $this
+ *
* @see https://datatables.net/reference/option/stateSaveParams
*/
- public function stateSaveParams($script)
+ public function stateSaveParams(string $script): static
{
$this->attributes['stateSaveParams'] = $script;
diff --git a/src/Html/Options/HasColumns.php b/src/Html/Options/HasColumns.php
index f477a90..5444ce0 100644
--- a/src/Html/Options/HasColumns.php
+++ b/src/Html/Options/HasColumns.php
@@ -2,10 +2,9 @@
namespace Yajra\DataTables\Html\Options;
+use Illuminate\Contracts\Support\Arrayable;
use Illuminate\Support\Collection;
-use Illuminate\Support\Str;
use Yajra\DataTables\Html\Column;
-use Illuminate\Contracts\Support\Arrayable;
/**
* DataTables - Columns option builder.
@@ -17,11 +16,11 @@ trait HasColumns
/**
* Set columnDefs option value.
*
- * @param mixed $value
* @return $this
+ *
* @see https://datatables.net/reference/option/columnDefs
*/
- public function columnDefs($value)
+ public function columnDefs(array|Arrayable|callable $value): static
{
if (is_callable($value)) {
$value = app()->call($value);
@@ -31,6 +30,14 @@ public function columnDefs($value)
$value = $value->toArray();
}
+ if (is_array($value)) {
+ foreach ($value as $key => $def) {
+ if ($def instanceof Arrayable) {
+ $value[$key] = $def->toArray();
+ }
+ }
+ }
+
$this->attributes['columnDefs'] = $value;
return $this;
@@ -39,11 +46,11 @@ public function columnDefs($value)
/**
* Add a columnDef option.
*
- * @param mixed $value
* @return $this
+ *
* @see https://datatables.net/reference/option/columnDefs
*/
- public function addColumnDef($value)
+ public function addColumnDef(array|Arrayable|callable $value): static
{
if (is_callable($value)) {
$value = app()->call($value);
@@ -61,35 +68,35 @@ public function addColumnDef($value)
/**
* Set columns option value.
*
- * @param array $columns
* @return $this
+ *
* @see https://datatables.net/reference/option/columns
*/
- public function columns(array $columns)
+ public function columns(array $columns): static
{
$this->collection = new Collection;
foreach ($columns as $key => $value) {
if (! is_a($value, Column::class)) {
if (is_array($value)) {
- $attributes = array_merge(
- [
- 'name' => $value['name'] ?? $value['data'] ?? $key,
- 'data' => $value['data'] ?? $key,
- ],
- $this->setTitle($key, $value)
- );
+ $attributes = array_merge($value, [
+ 'name' => $value['name'] ?? $value['data'] ?? $key,
+ 'data' => $value['data'] ?? $key,
+ ]);
} else {
$attributes = [
'name' => $value,
'data' => $value,
- 'title' => $this->getQualifiedTitle($value),
];
}
$this->collection->push(new Column($attributes));
} else {
- $this->collection->push($value);
+
+ // Only add the column if it is authorized, otherwise ignore it.
+ if ($value->isAuthorized()) {
+ $this->collection->push($value);
+ }
}
}
@@ -97,41 +104,29 @@ public function columns(array $columns)
}
/**
- * Set title attribute of an array if not set.
+ * Add a column in collection using attributes.
*
- * @param string $title
- * @param array $attributes
- * @return array
+ * @return $this
*/
- public function setTitle($title, array $attributes)
+ public function addColumn(array|Column $attributes): static
{
- if (! isset($attributes['title'])) {
- $attributes['title'] = $this->getQualifiedTitle($title);
+ if (is_array($attributes)) {
+ $this->collection->push(new Column($attributes));
+ } else {
+ $this->add($attributes);
}
- return $attributes;
- }
-
- /**
- * Convert string into a readable title.
- *
- * @param string $title
- * @return string
- */
- public function getQualifiedTitle($title)
- {
- return Str::title(str_replace(['.', '_'], ' ', Str::snake($title)));
+ return $this;
}
/**
- * Add a column in collection usingsl attributes.
+ * Add a Column object in collection.
*
- * @param array $attributes
* @return $this
*/
- public function addColumn(array $attributes)
+ public function add(Column $column): static
{
- $this->collection->push(new Column($attributes));
+ $this->collection->push($column);
return $this;
}
@@ -139,10 +134,9 @@ public function addColumn(array $attributes)
/**
* Add a Column object at the beginning of collection.
*
- * @param \Yajra\DataTables\Html\Column $column
* @return $this
*/
- public function addBefore(Column $column)
+ public function addBefore(Column $column): static
{
$this->collection->prepend($column);
@@ -152,25 +146,15 @@ public function addBefore(Column $column)
/**
* Add a column at the beginning of collection using attributes.
*
- * @param array $attributes
- * @return $this
- */
- public function addColumnBefore(array $attributes)
- {
- $this->collection->prepend(new Column($attributes));
-
- return $this;
- }
-
- /**
- * Add a Column object in collection.
- *
- * @param \Yajra\DataTables\Html\Column $column
* @return $this
*/
- public function add(Column $column)
+ public function addColumnBefore(array|Column $attributes): static
{
- $this->collection->push($column);
+ if (is_array($attributes)) {
+ $this->collection->prepend(new Column($attributes));
+ } else {
+ $this->addBefore($attributes);
+ }
return $this;
}
@@ -178,9 +162,9 @@ public function add(Column $column)
/**
* Get collection of columns.
*
- * @return \Illuminate\Support\Collection
+ * @return \Illuminate\Support\Collection
*/
- public function getColumns()
+ public function getColumns(): Collection
{
return $this->collection;
}
@@ -188,15 +172,14 @@ public function getColumns()
/**
* Remove column by name.
*
- * @param array $names
+ * @param array $names
* @return $this
*/
- public function removeColumn(...$names)
+ public function removeColumn(...$names): static
{
foreach ($names as $name) {
- $this->collection = $this->collection->filter(function (Column $column) use ($name) {
- return $column->name !== $name;
- })->flatten();
+ // @phpstan-ignore-next-line
+ $this->collection = $this->collection->filter(fn (Column $column) => $column->name !== $name)->flatten();
}
return $this;
diff --git a/src/Html/Options/HasFeatures.php b/src/Html/Options/HasFeatures.php
index 4db77e7..4a69b75 100644
--- a/src/Html/Options/HasFeatures.php
+++ b/src/Html/Options/HasFeatures.php
@@ -12,11 +12,11 @@ trait HasFeatures
/**
* Set autoWidth option value.
*
- * @param bool $value
* @return $this
+ *
* @see https://datatables.net/reference/option/autoWidth
*/
- public function autoWidth(bool $value = true)
+ public function autoWidth(bool $value = true): static
{
$this->attributes['autoWidth'] = $value;
@@ -26,11 +26,11 @@ public function autoWidth(bool $value = true)
/**
* Set deferRender option value.
*
- * @param bool $value
* @return $this
+ *
* @see https://datatables.net/reference/option/deferRender
*/
- public function deferRender(bool $value = true)
+ public function deferRender(bool $value = true): static
{
$this->attributes['deferRender'] = $value;
@@ -40,11 +40,11 @@ public function deferRender(bool $value = true)
/**
* Set info option value.
*
- * @param bool $value
* @return $this
+ *
* @see https://datatables.net/reference/option/info
*/
- public function info(bool $value = true)
+ public function info(bool $value = true): static
{
$this->attributes['info'] = $value;
@@ -54,11 +54,11 @@ public function info(bool $value = true)
/**
* Set lengthChange option value.
*
- * @param bool $value
* @return $this
+ *
* @see https://datatables.net/reference/option/lengthChange
*/
- public function lengthChange(bool $value = true)
+ public function lengthChange(bool $value = true): static
{
$this->attributes['lengthChange'] = $value;
@@ -68,11 +68,11 @@ public function lengthChange(bool $value = true)
/**
* Set ordering option value.
*
- * @param bool $value
* @return $this
+ *
* @see https://datatables.net/reference/option/ordering
*/
- public function ordering(bool $value = true)
+ public function ordering(bool $value = true): static
{
$this->attributes['ordering'] = $value;
@@ -82,11 +82,11 @@ public function ordering(bool $value = true)
/**
* Set processing option value.
*
- * @param bool $value
* @return $this
+ *
* @see https://datatables.net/reference/option/processing
*/
- public function processing(bool $value = true)
+ public function processing(bool $value = true): static
{
$this->attributes['processing'] = $value;
@@ -96,11 +96,11 @@ public function processing(bool $value = true)
/**
* Set scrollX option value.
*
- * @param bool $value
* @return $this
+ *
* @see https://datatables.net/reference/option/scrollX
*/
- public function scrollX(bool $value = true)
+ public function scrollX(bool $value = true): static
{
$this->attributes['scrollX'] = $value;
@@ -110,11 +110,11 @@ public function scrollX(bool $value = true)
/**
* Set scrollY option value.
*
- * @param bool|mixed $value
* @return $this
+ *
* @see https://datatables.net/reference/option/scrollY
*/
- public function scrollY($value = true)
+ public function scrollY(bool|string $value = true): static
{
$this->attributes['scrollY'] = $value;
@@ -124,11 +124,11 @@ public function scrollY($value = true)
/**
* Set paging option value.
*
- * @param bool $value
* @return $this
+ *
* @see https://datatables.net/reference/option/paging
*/
- public function paging(bool $value = true)
+ public function paging(bool $value = true): static
{
$this->attributes['paging'] = $value;
@@ -138,11 +138,11 @@ public function paging(bool $value = true)
/**
* Set searching option value.
*
- * @param bool $value
* @return $this
+ *
* @see https://datatables.net/reference/option/searching
*/
- public function searching(bool $value = true)
+ public function searching(bool $value = true): static
{
$this->attributes['searching'] = $value;
@@ -152,11 +152,11 @@ public function searching(bool $value = true)
/**
* Set serverSide option value.
*
- * @param bool $value
* @return $this
+ *
* @see https://datatables.net/reference/option/serverSide
*/
- public function serverSide(bool $value = true)
+ public function serverSide(bool $value = true): static
{
$this->attributes['serverSide'] = $value;
@@ -166,11 +166,11 @@ public function serverSide(bool $value = true)
/**
* Set stateSave option value.
*
- * @param bool $value
* @return $this
+ *
* @see https://datatables.net/reference/option/stateSave
*/
- public function stateSave(bool $value = true)
+ public function stateSave(bool $value = true): static
{
$this->attributes['stateSave'] = $value;
diff --git a/src/Html/Options/HasInternationalisation.php b/src/Html/Options/HasInternationalisation.php
index 7c93a4e..6ca09bb 100644
--- a/src/Html/Options/HasInternationalisation.php
+++ b/src/Html/Options/HasInternationalisation.php
@@ -2,8 +2,6 @@
namespace Yajra\DataTables\Html\Options;
-use Yajra\DataTables\Html\Options\Languages;
-
/**
* DataTables - Internationalisation option builder.
*
@@ -17,33 +15,31 @@ trait HasInternationalisation
use Languages\Select;
/**
- * Set language option value.
+ * Set language decimal option value.
*
- * @param string|array $value
* @return $this
- * @see https://datatables.net/reference/option/language
+ *
+ * @see https://datatables.net/reference/option/language.decimal
*/
- public function language($value)
+ public function languageDecimal(string $value): static
{
- if (is_array($value)) {
- $this->attributes['language'] = $value;
- } else {
- $this->attributes['language']['url'] = $value;
- }
-
- return $this;
+ return $this->language(['decimal' => $value]);
}
/**
- * Set language decimal option value.
+ * Set language option value.
*
- * @param string $value
* @return $this
- * @see https://datatables.net/reference/option/language.decimal
+ *
+ * @see https://datatables.net/reference/option/language
*/
- public function languageDecimal($value)
+ public function language(array|string $value): static
{
- $this->attributes['language']['decimal'] = $value;
+ if (is_array($value)) {
+ $this->attributes['language'] = array_merge((array) ($this->attributes['language'] ?? []), $value);
+ } else {
+ $this->attributes['language']['url'] = $value;
+ }
return $this;
}
@@ -51,182 +47,165 @@ public function languageDecimal($value)
/**
* Set language emptyTable option value.
*
- * @param string $value
* @return $this
+ *
* @see https://datatables.net/reference/option/language.emptyTable
*/
- public function languageEmptyTable($value)
+ public function languageEmptyTable(string $value): static
{
- $this->attributes['language']['emptyTable'] = $value;
-
- return $this;
+ return $this->language(['emptyTable' => $value]);
}
/**
* Set language info option value.
*
- * @param string $value
* @return $this
+ *
* @see https://datatables.net/reference/option/language.info
*/
- public function languageInfo($value)
+ public function languageInfo(string $value): static
{
- $this->attributes['language']['info'] = $value;
-
- return $this;
+ return $this->language(['info' => $value]);
}
/**
* Set language infoEmpty option value.
*
- * @param string $value
* @return $this
+ *
* @see https://datatables.net/reference/option/language.infoEmpty
*/
- public function languageInfoEmpty($value)
+ public function languageInfoEmpty(string $value): static
{
- $this->attributes['language']['infoEmpty'] = $value;
-
- return $this;
+ return $this->language(['infoEmpty' => $value]);
}
/**
* Set language infoFiltered option value.
*
- * @param string $value
* @return $this
+ *
* @see https://datatables.net/reference/option/language.infoFiltered
*/
- public function languageInfoFiltered($value)
+ public function languageInfoFiltered(string $value): static
{
- $this->attributes['language']['infoFiltered'] = $value;
-
- return $this;
+ return $this->language(['infoFiltered' => $value]);
}
/**
* Set language infoPostFix option value.
*
- * @param string $value
* @return $this
+ *
* @see https://datatables.net/reference/option/language.infoPostFix
*/
- public function languageInfoPostFix($value)
+ public function languageInfoPostFix(string $value): static
{
- $this->attributes['language']['infoPostFix'] = $value;
-
- return $this;
+ return $this->language(['infoPostFix' => $value]);
}
/**
* Set language lengthMenu option value.
*
- * @param string $value
* @return $this
+ *
* @see https://datatables.net/reference/option/language.lengthMenu
*/
- public function languageLengthMenu($value)
+ public function languageLengthMenu(string $value): static
{
- $this->attributes['language']['lengthMenu'] = $value;
-
- return $this;
+ return $this->language(['lengthMenu' => $value]);
}
/**
* Set language loadingRecords option value.
*
- * @param string $value
* @return $this
+ *
* @see https://datatables.net/reference/option/language.loadingRecords
*/
- public function languageLoadingRecords($value)
+ public function languageLoadingRecords(string $value): static
{
- $this->attributes['language']['loadingRecords'] = $value;
-
- return $this;
+ return $this->language(['loadingRecords' => $value]);
}
/**
* Set language processing option value.
*
- * @param string $value
* @return $this
+ *
* @see https://datatables.net/reference/option/language.processing
*/
- public function languageProcessing($value)
+ public function languageProcessing(string $value): static
{
- $this->attributes['language']['processing'] = $value;
-
- return $this;
+ return $this->language(['processing' => $value]);
}
/**
* Set language search option value.
*
- * @param string $value
* @return $this
+ *
* @see https://datatables.net/reference/option/language.search
*/
- public function languageSearch($value)
+ public function languageSearch(string $value): static
{
- $this->attributes['language']['search'] = $value;
-
- return $this;
+ return $this->language(['search' => $value]);
}
/**
* Set language searchPlaceholder option value.
*
- * @param string $value
* @return $this
+ *
* @see https://datatables.net/reference/option/language.searchPlaceholder
*/
- public function languageSearchPlaceholder($value)
+ public function languageSearchPlaceholder(string $value): static
{
- $this->attributes['language']['searchPlaceholder'] = $value;
-
- return $this;
+ return $this->language(['searchPlaceholder' => $value]);
}
/**
* Set language thousands option value.
*
- * @param string $value
* @return $this
+ *
* @see https://datatables.net/reference/option/language.thousands
*/
- public function languageThousands($value)
+ public function languageThousands(string $value): static
{
- $this->attributes['language']['thousands'] = $value;
-
- return $this;
+ return $this->language(['thousands' => $value]);
}
/**
* Set language url option value.
*
- * @param string $value
* @return $this
+ *
* @see https://datatables.net/reference/option/language.url
*/
- public function languageUrl($value)
+ public function languageUrl(string $value): static
{
- $this->attributes['language']['url'] = $value;
-
- return $this;
+ return $this->language(['url' => $value]);
}
/**
* Set language zeroRecords option value.
*
- * @param string $value
* @return $this
+ *
* @see https://datatables.net/reference/option/language.zeroRecords
*/
- public function languageZeroRecords($value)
+ public function languageZeroRecords(string $value): static
{
- $this->attributes['language']['zeroRecords'] = $value;
+ return $this->language(['zeroRecords' => $value]);
+ }
- return $this;
+ public function getLanguage(?string $key = null): mixed
+ {
+ if (is_null($key)) {
+ return $this->attributes['language'] ?? [];
+ }
+
+ return $this->attributes['language'][$key] ?? '';
}
}
diff --git a/src/Html/Options/Languages/Aria.php b/src/Html/Options/Languages/Aria.php
index 0ca389c..a32f936 100644
--- a/src/Html/Options/Languages/Aria.php
+++ b/src/Html/Options/Languages/Aria.php
@@ -7,112 +7,96 @@ trait Aria
/**
* Set language aria option value.
*
- * @param array $value
* @return $this
+ *
* @see https://datatables.net/reference/option/language.aria
*/
- public function languageAria(array $value)
+ public function languageAria(array $value): static
{
- $this->attributes['language']['aria'] = $value;
-
- return $this;
+ return $this->language(['aria' => $value]);
}
/**
* Set language aria paginate option value.
*
- * @param array $value
* @return $this
+ *
* @see https://datatables.net/reference/option/language.aria.paginate
*/
- public function languageAriaPaginate(array $value)
+ public function languageAriaPaginate(array $value): static
{
- $this->attributes['language']['aria']['paginate'] = $value;
-
- return $this;
+ return $this->languageAria(['paginate' => $value]);
}
/**
* Set language aria paginate first option value.
*
- * @param string $value
* @return $this
+ *
* @see https://datatables.net/reference/option/language.aria.paginate.first
*/
- public function languageAriaPaginateFirst($value)
+ public function languageAriaPaginateFirst(string $value): static
{
- $this->attributes['language']['aria']['paginate']['first'] = $value;
-
- return $this;
+ return $this->languageAriaPaginate(['first' => $value]);
}
/**
* Set language aria paginate last option value.
*
- * @param string $value
* @return $this
+ *
* @see https://datatables.net/reference/option/language.aria.paginate.last
*/
- public function languageAriaPaginateLast($value)
+ public function languageAriaPaginateLast(string $value): static
{
- $this->attributes['language']['aria']['paginate']['last'] = $value;
-
- return $this;
+ return $this->languageAriaPaginate(['last' => $value]);
}
/**
* Set language aria paginate next option value.
*
- * @param string $value
* @return $this
+ *
* @see https://datatables.net/reference/option/language.aria.paginate.next
*/
- public function languageAriaPaginateNext($value)
+ public function languageAriaPaginateNext(string $value): static
{
- $this->attributes['language']['aria']['paginate']['next'] = $value;
-
- return $this;
+ return $this->languageAriaPaginate(['next' => $value]);
}
/**
* Set language aria paginate previous option value.
*
- * @param string $value
* @return $this
+ *
* @see https://datatables.net/reference/option/language.aria.paginate.previous
*/
- public function languageAriaPaginatePrevious($value)
+ public function languageAriaPaginatePrevious(string $value): static
{
- $this->attributes['language']['aria']['paginate']['previous'] = $value;
-
- return $this;
+ return $this->languageAriaPaginate(['previous' => $value]);
}
/**
* Set language aria sortAscending option value.
*
- * @param string $value
* @return $this
+ *
* @see https://datatables.net/reference/option/language.aria.sortAscending
*/
- public function languageAriaSortAscending($value)
+ public function languageAriaSortAscending(string $value): static
{
- $this->attributes['language']['aria']['sortAscending'] = $value;
-
- return $this;
+ return $this->languageAria(['sortAscending' => $value]);
}
/**
* Set language aria sortDescending option value.
*
- * @param string $value
* @return $this
+ *
* @see https://datatables.net/reference/option/language.aria.sortDescending
*/
- public function languageAriaSortDescending($value)
+ public function languageAriaSortDescending(string $value): static
{
- $this->attributes['language']['aria']['sortDescending'] = $value;
-
- return $this;
+ return $this->languageAria(['sortDescending' => $value]);
}
}
diff --git a/src/Html/Options/Languages/AutoFill.php b/src/Html/Options/Languages/AutoFill.php
index 5207d9a..9fa96c5 100644
--- a/src/Html/Options/Languages/AutoFill.php
+++ b/src/Html/Options/Languages/AutoFill.php
@@ -7,112 +7,96 @@ trait AutoFill
/**
* Set language autoFill option value.
*
- * @param array $value
* @return $this
+ *
* @see https://datatables.net/reference/option/language.autoFill
*/
- public function languageAutoFill(array $value)
+ public function languageAutoFill(array $value): static
{
- $this->attributes['language']['autoFill'] = $value;
-
- return $this;
+ return $this->language(['autoFill' => $value]);
}
/**
* Set language autoFill button option value.
*
- * @param string $value
* @return $this
+ *
* @see https://datatables.net/reference/option/language.autoFill.button
*/
- public function languageAutoFillButton($value)
+ public function languageAutoFillButton(string $value): static
{
- $this->attributes['language']['autoFill']['button'] = $value;
-
- return $this;
+ return $this->languageAutoFill(['button' => $value]);
}
/**
* Set language autoFill cancel option value.
*
- * @param string $value
* @return $this
+ *
* @see https://datatables.net/reference/option/language.autoFill.cancel
*/
- public function languageAutoFillCancel($value)
+ public function languageAutoFillCancel(string $value): static
{
- $this->attributes['language']['autoFill']['cancel'] = $value;
-
- return $this;
+ return $this->languageAutoFill(['cancel' => $value]);
}
/**
* Set language autoFill fill option value.
*
- * @param string $value
* @return $this
+ *
* @see https://datatables.net/reference/option/language.autoFill.fill
*/
- public function languageAutoFillFill($value)
+ public function languageAutoFillFill(string $value): static
{
- $this->attributes['language']['autoFill']['fill'] = $value;
-
- return $this;
+ return $this->languageAutoFill(['fill' => $value]);
}
/**
* Set language autoFill fillHorizontal option value.
*
- * @param string $value
* @return $this
+ *
* @see https://datatables.net/reference/option/language.autoFill.fillHorizontal
*/
- public function languageAutoFillFillHorizontal($value)
+ public function languageAutoFillFillHorizontal(string $value): static
{
- $this->attributes['language']['autoFill']['fillHorizontal'] = $value;
-
- return $this;
+ return $this->languageAutoFill(['fillHorizontal' => $value]);
}
/**
* Set language autoFill fillVertical option value.
*
- * @param string $value
* @return $this
+ *
* @see https://datatables.net/reference/option/language.autoFill.fillVertical
*/
- public function languageAutoFillFillVertical($value)
+ public function languageAutoFillFillVertical(string $value): static
{
- $this->attributes['language']['autoFill']['fillVertical'] = $value;
-
- return $this;
+ return $this->languageAutoFill(['fillVertical' => $value]);
}
/**
* Set language autoFill increment option value.
*
- * @param string $value
* @return $this
+ *
* @see https://datatables.net/reference/option/language.autoFill.increment
*/
- public function languageAutoFillIncrement($value)
+ public function languageAutoFillIncrement(string $value): static
{
- $this->attributes['language']['autoFill']['increment'] = $value;
-
- return $this;
+ return $this->languageAutoFill(['increment' => $value]);
}
/**
* Set language autoFill info option value.
*
- * @param string $value
* @return $this
+ *
* @see https://datatables.net/reference/option/language.autoFill.info
*/
- public function languageAutoFillInfo($value)
+ public function languageAutoFillInfo(string $value): static
{
- $this->attributes['language']['autoFill']['info'] = $value;
-
- return $this;
+ return $this->languageAutoFill(['info' => $value]);
}
}
diff --git a/src/Html/Options/Languages/Paginate.php b/src/Html/Options/Languages/Paginate.php
index 46fa9a8..c22d261 100644
--- a/src/Html/Options/Languages/Paginate.php
+++ b/src/Html/Options/Languages/Paginate.php
@@ -7,70 +7,60 @@ trait Paginate
/**
* Set language aria paginate option value.
*
- * @param array $value
* @return $this
+ *
* @see https://datatables.net/reference/option/language.paginate
*/
- public function languagePaginate(array $value)
+ public function languagePaginate(array $value): static
{
- $this->attributes['language']['paginate'] = $value;
-
- return $this;
+ return $this->language(['paginate' => $value]);
}
/**
* Set language aria paginate first option value.
*
- * @param string $value
* @return $this
+ *
* @see https://datatables.net/reference/option/language.paginate.first
*/
- public function languagePaginateFirst($value)
+ public function languagePaginateFirst(string $value): static
{
- $this->attributes['language']['paginate']['first'] = $value;
-
- return $this;
+ return $this->languagePaginate(['first' => $value]);
}
/**
* Set language aria paginate last option value.
*
- * @param string $value
* @return $this
+ *
* @see https://datatables.net/reference/option/language.paginate.last
*/
- public function languagePaginateLast($value)
+ public function languagePaginateLast(string $value): static
{
- $this->attributes['language']['paginate']['last'] = $value;
-
- return $this;
+ return $this->languagePaginate(['last' => $value]);
}
/**
* Set language aria paginate next option value.
*
- * @param string $value
* @return $this
+ *
* @see https://datatables.net/reference/option/language.paginate.next
*/
- public function languagePaginateNext($value)
+ public function languagePaginateNext(string $value): static
{
- $this->attributes['language']['paginate']['next'] = $value;
-
- return $this;
+ return $this->languagePaginate(['next' => $value]);
}
/**
* Set language aria paginate previous option value.
*
- * @param string $value
* @return $this
+ *
* @see https://datatables.net/reference/option/language.paginate.previous
*/
- public function languagePaginatePrevious($value)
+ public function languagePaginatePrevious(string $value): static
{
- $this->attributes['language']['paginate']['previous'] = $value;
-
- return $this;
+ return $this->languagePaginate(['previous' => $value]);
}
}
diff --git a/src/Html/Options/Languages/Select.php b/src/Html/Options/Languages/Select.php
index 910c897..791c019 100644
--- a/src/Html/Options/Languages/Select.php
+++ b/src/Html/Options/Languages/Select.php
@@ -7,56 +7,48 @@ trait Select
/**
* Set language select option value.
*
- * @param array $value
* @return $this
+ *
* @see https://datatables.net/reference/option/language.select
*/
- public function languageSelect($value)
+ public function languageSelect(array $value): static
{
- $this->attributes['language']['select'] = $value;
-
- return $this;
+ return $this->language(['select' => $value]);
}
/**
* Set language select cells option value.
*
- * @param string|array $value
* @return $this
+ *
* @see https://datatables.net/reference/option/language.select.cells
*/
- public function languageSelectCells($value)
+ public function languageSelectCells(array|string $value): static
{
- $this->attributes['language']['select']['cells'] = $value;
-
- return $this;
+ return $this->languageSelect(['cells' => $value]);
}
/**
* Set language select columns option value.
*
- * @param string|array $value
* @return $this
+ *
* @see https://datatables.net/reference/option/language.select.columns
*/
- public function languageSelectColumns($value)
+ public function languageSelectColumns(array|string $value): static
{
- $this->attributes['language']['select']['columns'] = $value;
-
- return $this;
+ return $this->languageSelect(['columns' => $value]);
}
/**
* Set language select rows option value.
*
- * @param string|array $value
* @return $this
+ *
* @see https://datatables.net/reference/option/language.select.rows
*/
- public function languageSelectRows($value)
+ public function languageSelectRows(array|string $value): static
{
- $this->attributes['language']['select']['rows'] = $value;
-
- return $this;
+ return $this->languageSelect(['rows' => $value]);
}
}
diff --git a/src/Html/Options/Plugins/AutoFill.php b/src/Html/Options/Plugins/AutoFill.php
index 5e17405..e9ac52b 100644
--- a/src/Html/Options/Plugins/AutoFill.php
+++ b/src/Html/Options/Plugins/AutoFill.php
@@ -12,129 +12,120 @@
trait AutoFill
{
/**
- * Set autoFill option value.
- * Enable and configure the AutoFill extension for DataTables.
+ * Set autoFill alwaysAsk option value.
*
- * @param bool|array $value
* @return $this
- * @see https://datatables.net/reference/option/autoFill
+ *
+ * @see https://datatables.net/reference/option/autoFill.alwaysAsk
*/
- public function autoFill($value = true)
+ public function autoFillAlwaysAsk(bool $value = true): static
{
- $this->attributes['autoFill'] = $value;
-
- return $this;
+ return $this->autoFill(['alwaysAsk' => $value]);
}
/**
- * Set autoFill alwaysAsk option value.
+ * Set autoFill option value.
+ * Enable and configure the AutoFill extension for DataTables.
*
- * @param bool $value
* @return $this
- * @see https://datatables.net/reference/option/autoFill.alwaysAsk
+ *
+ * @see https://datatables.net/reference/option/autoFill
*/
- public function autoFillAlwaysAsk(bool $value = true)
+ public function autoFill(array|bool $value = true): static
{
- $this->attributes['autoFill']['alwaysAsk'] = $value;
-
- return $this;
+ return $this->setPluginAttribute('autoFill', $value);
}
/**
* Set autoFill columns option value.
*
- * @param mixed $value
* @return $this
+ *
* @see https://datatables.net/reference/option/autoFill.columns
*/
- public function autoFillColumns($value)
+ public function autoFillColumns(array|string $value): static
{
- $this->attributes['autoFill']['columns'] = $value;
-
- return $this;
+ return $this->autoFill(['columns' => $value]);
}
/**
* Set autoFill editor option value.
*
- * @param mixed $value
* @return $this
+ *
* @see https://datatables.net/reference/option/autoFill.editor
*/
- public function autoFillEditor($value)
+ public function autoFillEditor(string $value): static
{
- $this->attributes['autoFill']['editor'] = $value;
-
- return $this;
+ return $this->autoFill(['editor' => $value]);
}
/**
* Set autoFill enable option value.
*
- * @param bool $value
* @return $this
+ *
* @see https://datatables.net/reference/option/autoFill.enable
*/
- public function autoFillEnable(bool $value = true)
+ public function autoFillEnable(bool $value = true): static
{
- $this->attributes['autoFill']['enable'] = $value;
-
- return $this;
+ return $this->autoFill(['enable' => $value]);
}
/**
* Set autoFill focus option value.
*
- * @param mixed $value
* @return $this
+ *
* @see https://datatables.net/reference/option/autoFill.focus
*/
- public function autoFillFocus($value = null)
+ public function autoFillFocus(?string $value = null): static
{
- $this->attributes['autoFill']['focus'] = $value;
-
- return $this;
+ return $this->autoFill(['focus' => $value]);
}
/**
* Set autoFill horizontal option value.
*
- * @param bool $value
* @return $this
+ *
* @see https://datatables.net/reference/option/autoFill.horizontal
*/
- public function autoFillHorizontal(bool $value = true)
+ public function autoFillHorizontal(bool $value = true): static
{
- $this->attributes['autoFill']['horizontal'] = $value;
-
- return $this;
+ return $this->autoFill(['horizontal' => $value]);
}
/**
* Set autoFill update option value.
*
- * @param bool $value
* @return $this
+ *
* @see https://datatables.net/reference/option/autoFill.update
*/
- public function autoFillUpdate(bool $value = true)
+ public function autoFillUpdate(bool $value = true): static
{
- $this->attributes['autoFill']['update'] = $value;
-
- return $this;
+ return $this->autoFill(['update' => $value]);
}
/**
* Set autoFill vertical option value.
*
- * @param bool $value
* @return $this
+ *
* @see https://datatables.net/reference/option/autoFill.vertical
*/
- public function autoFillVertical(bool $value = true)
+ public function autoFillVertical(bool $value = true): static
+ {
+ return $this->autoFill(['vertical' => $value]);
+ }
+
+ public function getAutoFill(?string $key = null): mixed
{
- $this->attributes['autoFill']['vertical'] = $value;
+ if (is_null($key)) {
+ return $this->attributes['autoFill'] ?? true;
+ }
- return $this;
+ return $this->attributes['autoFill'][$key] ?? false;
}
}
diff --git a/src/Html/Options/Plugins/Buttons.php b/src/Html/Options/Plugins/Buttons.php
index fbced7c..91378f1 100644
--- a/src/Html/Options/Plugins/Buttons.php
+++ b/src/Html/Options/Plugins/Buttons.php
@@ -3,6 +3,7 @@
namespace Yajra\DataTables\Html\Options\Plugins;
use Illuminate\Contracts\Support\Arrayable;
+use Yajra\DataTables\Html\Button;
/**
* DataTables - Buttons plugin option builder.
@@ -15,12 +16,15 @@ trait Buttons
/**
* Attach multiple buttons to builder.
*
- * @param array|mixed ...$buttons
+ * @param array|mixed ...$buttons
* @return $this
+ *
* @see https://www.datatables.net/extensions/buttons/
*/
- public function buttons(...$buttons)
+ public function buttons(...$buttons): static
{
+ $this->attributes['buttons'] = [];
+
if (is_array($buttons[0])) {
$buttons = $buttons[0];
}
@@ -31,4 +35,22 @@ public function buttons(...$buttons)
return $this;
}
+
+ /**
+ * @return $this
+ */
+ public function addButton(Button $button): static
+ {
+ $this->attributes['buttons'][] = $button->toArray();
+
+ return $this;
+ }
+
+ /**
+ * Get builder buttons.
+ */
+ public function getButtons(): array
+ {
+ return $this->attributes['buttons'] ?? [];
+ }
}
diff --git a/src/Html/Options/Plugins/ColReorder.php b/src/Html/Options/Plugins/ColReorder.php
index fc67f1a..561b980 100644
--- a/src/Html/Options/Plugins/ColReorder.php
+++ b/src/Html/Options/Plugins/ColReorder.php
@@ -12,87 +12,84 @@
trait ColReorder
{
/**
- * Set colReorder option value.
- * Enable and configure the AutoFill extension for DataTables.
+ * Set colReorder enable option value.
*
- * @param bool|array $value
* @return $this
- * @see https://datatables.net/reference/option/colReorder
+ *
+ * @see https://datatables.net/reference/option/colReorder.enable
*/
- public function colReorder($value = true)
+ public function colReorderEnable(bool $value = true): static
{
- $this->attributes['colReorder'] = $value;
-
- return $this;
+ return $this->colReorder(['enable' => $value]);
}
/**
- * Set colReorder enable option value.
+ * Set colReorder option value.
+ * Enable and configure the AutoFill extension for DataTables.
*
- * @param bool $value
* @return $this
- * @see https://datatables.net/reference/option/colReorder.enable
+ *
+ * @see https://datatables.net/reference/option/colReorder
*/
- public function colReorderEnable(bool $value = true)
+ public function colReorder(array|bool $value = true): static
{
- $this->attributes['colReorder']['enable'] = $value;
-
- return $this;
+ return $this->setPluginAttribute('colReorder', $value);
}
/**
* Set colReorder fixedColumnsLeft option value.
*
- * @param int $value
* @return $this
+ *
* @see https://datatables.net/reference/option/colReorder.fixedColumnsLeft
*/
- public function colReorderFixedColumnsLeft(int $value = 0)
+ public function colReorderFixedColumnsLeft(int $value = 0): static
{
- $this->attributes['colReorder']['fixedColumnsLeft'] = $value;
-
- return $this;
+ return $this->colReorder(['fixedColumnsLeft' => $value]);
}
/**
* Set colReorder fixedColumnsRight option value.
*
- * @param int $value
* @return $this
+ *
* @see https://datatables.net/reference/option/colReorder.fixedColumnsRight
*/
- public function colReorderFixedColumnsRight(int $value = 0)
+ public function colReorderFixedColumnsRight(int $value = 0): static
{
- $this->attributes['colReorder']['fixedColumnsRight'] = $value;
-
- return $this;
+ return $this->colReorder(['fixedColumnsRight' => $value]);
}
/**
* Set colReorder order option value.
*
- * @param array $value
* @return $this
+ *
* @see https://datatables.net/reference/option/colReorder.order
*/
- public function colReorderOrder(array $value = [])
+ public function colReorderOrder(array $value = []): static
{
- $this->attributes['colReorder']['order'] = $value;
-
- return $this;
+ return $this->colReorder(['order' => $value]);
}
/**
* Set colReorder realtime option value.
*
- * @param bool $value
* @return $this
+ *
* @see https://datatables.net/reference/option/colReorder.realtime
*/
- public function colReorderRealtime(bool $value = true)
+ public function colReorderRealtime(bool $value = true): static
+ {
+ return $this->colReorder(['realtime' => $value]);
+ }
+
+ public function getColReorder(?string $key = null): mixed
{
- $this->attributes['colReorder']['realtime'] = $value;
+ if (is_null($key)) {
+ return $this->attributes['colReorder'] ?? true;
+ }
- return $this;
+ return $this->attributes['colReorder'][$key] ?? false;
}
}
diff --git a/src/Html/Options/Plugins/FixedColumns.php b/src/Html/Options/Plugins/FixedColumns.php
index d63e607..5926f58 100644
--- a/src/Html/Options/Plugins/FixedColumns.php
+++ b/src/Html/Options/Plugins/FixedColumns.php
@@ -12,58 +12,59 @@
trait FixedColumns
{
/**
- * Set fixedColumns option value.
+ * Set fixedColumns heightMatch option value.
*
- * @param bool|array $value
* @return $this
- * @see https://datatables.net/reference/option/fixedColumns
+ *
+ * @see https://datatables.net/reference/option/fixedColumns.heightMatch
*/
- public function fixedColumns($value = true)
+ public function fixedColumnsHeightMatch(string $value = 'semiauto'): static
{
- $this->attributes['fixedColumns'] = $value;
-
- return $this;
+ return $this->fixedColumns(['heightMatch' => $value]);
}
/**
- * Set fixedColumns heightMatch option value.
+ * Set fixedColumns option value.
*
- * @param string $value
* @return $this
- * @see https://datatables.net/reference/option/fixedColumns.heightMatch
+ *
+ * @see https://datatables.net/reference/option/fixedColumns
*/
- public function fixedColumnsHeightMatch($value = 'semiauto')
+ public function fixedColumns(array|bool $value = true): static
{
- $this->attributes['fixedColumns']['heightMatch'] = $value;
-
- return $this;
+ return $this->setPluginAttribute('fixedColumns', $value);
}
/**
* Set fixedColumns leftColumns option value.
*
- * @param int $value
* @return $this
+ *
* @see https://datatables.net/reference/option/fixedColumns.leftColumns
*/
- public function fixedColumnsLeftColumns(int $value = 1)
+ public function fixedColumnsLeftColumns(int $value = 1): static
{
- $this->attributes['fixedColumns']['leftColumns'] = $value;
-
- return $this;
+ return $this->fixedColumns(['leftColumns' => $value]);
}
/**
* Set fixedColumns rightColumns option value.
*
- * @param int $value
* @return $this
+ *
* @see https://datatables.net/reference/option/fixedColumns.rightColumns
*/
- public function fixedColumnsRightColumns(int $value = 0)
+ public function fixedColumnsRightColumns(int $value = 0): static
+ {
+ return $this->fixedColumns(['rightColumns' => $value]);
+ }
+
+ public function getFixedColumns(?string $key = null): mixed
{
- $this->attributes['fixedColumns']['rightColumns'] = $value;
+ if (is_null($key)) {
+ return $this->attributes['fixedColumns'] ?? true;
+ }
- return $this;
+ return $this->attributes['fixedColumns'][$key] ?? false;
}
}
diff --git a/src/Html/Options/Plugins/FixedHeader.php b/src/Html/Options/Plugins/FixedHeader.php
index 2a34429..54b5301 100644
--- a/src/Html/Options/Plugins/FixedHeader.php
+++ b/src/Html/Options/Plugins/FixedHeader.php
@@ -12,72 +12,71 @@
trait FixedHeader
{
/**
- * Set fixedHeader option value.
+ * Set fixedHeader footer option value.
*
- * @param bool|array $value
* @return $this
- * @see https://datatables.net/reference/option/fixedHeader
+ *
+ * @see https://datatables.net/reference/option/fixedHeader.footer
*/
- public function fixedHeader($value = true)
+ public function fixedHeaderFooter(bool $value = true): static
{
- $this->attributes['fixedHeader'] = $value;
-
- return $this;
+ return $this->fixedHeader(['footer' => $value]);
}
/**
- * Set fixedHeader footer option value.
+ * Set fixedHeader option value.
*
- * @param bool $value
* @return $this
- * @see https://datatables.net/reference/option/fixedHeader.footer
+ *
+ * @see https://datatables.net/reference/option/fixedHeader
*/
- public function fixedHeaderFooter(bool $value = true)
+ public function fixedHeader(array|bool $value = true): static
{
- $this->attributes['fixedHeader']['footer'] = $value;
-
- return $this;
+ return $this->setPluginAttribute('fixedHeader', $value);
}
/**
* Set fixedHeader footerOffset option value.
*
- * @param int $value
* @return $this
+ *
* @see https://datatables.net/reference/option/fixedHeader.footerOffset
*/
- public function fixedHeaderFooterOffset(int $value = 0)
+ public function fixedHeaderFooterOffset(int $value = 0): static
{
- $this->attributes['fixedHeader']['footerOffset'] = $value;
-
- return $this;
+ return $this->fixedHeader(['footerOffset' => $value]);
}
/**
* Set fixedHeader header option value.
*
- * @param bool $value
* @return $this
+ *
* @see https://datatables.net/reference/option/fixedHeader.header
*/
- public function fixedHeaderHeader(bool $value = true)
+ public function fixedHeaderHeader(bool $value = true): static
{
- $this->attributes['fixedHeader']['header'] = $value;
-
- return $this;
+ return $this->fixedHeader(['header' => $value]);
}
/**
* Set fixedHeader headerOffset option value.
*
- * @param int $value
* @return $this
+ *
* @see https://datatables.net/reference/option/fixedHeader.headerOffset
*/
- public function fixedHeaderHeaderOffset(int $value = 0)
+ public function fixedHeaderHeaderOffset(int $value = 0): static
+ {
+ return $this->fixedHeader(['headerOffset' => $value]);
+ }
+
+ public function getFixedHeader(?string $key = null): mixed
{
- $this->attributes['fixedHeader']['headerOffset'] = $value;
+ if (is_null($key)) {
+ return $this->attributes['fixedHeader'] ?? true;
+ }
- return $this;
+ return $this->attributes['fixedHeader'][$key] ?? false;
}
}
diff --git a/src/Html/Options/Plugins/KeyTable.php b/src/Html/Options/Plugins/KeyTable.php
index 4b84e09..b34f048 100644
--- a/src/Html/Options/Plugins/KeyTable.php
+++ b/src/Html/Options/Plugins/KeyTable.php
@@ -12,184 +12,167 @@
trait KeyTable
{
/**
- * Set keys option value.
+ * Set keys blurable option value.
*
- * @param bool|array $value
* @return $this
- * @see https://datatables.net/reference/option/keys
+ *
+ * @see https://datatables.net/reference/option/keys.blurable
*/
- public function keys($value = true)
+ public function keysBlurable(bool $value = true): static
{
- $this->attributes['keys'] = $value;
-
- return $this;
+ return $this->keys(['blurable' => $value]);
}
/**
- * Set keys blurable option value.
+ * Set keys option value.
*
- * @param bool $value
* @return $this
- * @see https://datatables.net/reference/option/keys.blurable
+ *
+ * @see https://datatables.net/reference/option/keys
*/
- public function keysBlurable(bool $value = true)
+ public function keys(array|bool $value = true): static
{
- $this->attributes['keys']['blurable'] = $value;
-
- return $this;
+ return $this->setPluginAttribute('keys', $value);
}
/**
* Set keys className option value.
*
- * @param string $value
* @return $this
+ *
* @see https://datatables.net/reference/option/keys.className
*/
- public function keysClassName($value = 'focus')
+ public function keysClassName(string $value = 'focus'): static
{
- $this->attributes['keys']['className'] = $value;
-
- return $this;
+ return $this->keys(['className' => $value]);
}
/**
* Set keys clipboard option value.
*
- * @param bool $value
* @return $this
+ *
* @see https://datatables.net/reference/option/keys.clipboard
*/
- public function keysClipboard(bool $value = true)
+ public function keysClipboard(bool $value = true): static
{
- $this->attributes['keys']['clipboard'] = $value;
-
- return $this;
+ return $this->keys(['clipboard' => $value]);
}
/**
* Set keys clipboardOrthogonal option value.
*
- * @param string $value
* @return $this
+ *
* @see https://datatables.net/reference/option/keys.clipboardOrthogonal
*/
- public function keysClipboardOrthogonal($value = 'display')
+ public function keysClipboardOrthogonal(string $value = 'display'): static
{
- $this->attributes['keys']['clipboardOrthogonal'] = $value;
-
- return $this;
+ return $this->keys(['clipboardOrthogonal' => $value]);
}
/**
* Set keys columns option value.
*
- * @param mixed $value
* @return $this
+ *
* @see https://datatables.net/reference/option/keys.columns
*/
- public function keysColumns($value)
+ public function keysColumns(array|string $value): static
{
- $this->attributes['keys']['columns'] = $value;
-
- return $this;
+ return $this->keys(['columns' => $value]);
}
/**
* Set keys editAutoSelect option value.
*
- * @param bool $value
* @return $this
+ *
* @see https://datatables.net/reference/option/keys.editAutoSelect
*/
- public function keysEditAutoSelect(bool $value = true)
+ public function keysEditAutoSelect(bool $value = true): static
{
- $this->attributes['keys']['editAutoSelect'] = $value;
-
- return $this;
+ return $this->keys(['editAutoSelect' => $value]);
}
/**
* Set keys editOnFocus option value.
*
- * @param bool $value
* @return $this
+ *
* @see https://datatables.net/reference/option/keys.editOnFocus
*/
- public function keysEditOnFocus(bool $value = true)
+ public function keysEditOnFocus(bool $value = true): static
{
- $this->attributes['keys']['editOnFocus'] = $value;
-
- return $this;
+ return $this->keys(['editOnFocus' => $value]);
}
/**
* Set keys editor option value.
*
- * @param mixed $value
* @return $this
+ *
* @see https://datatables.net/reference/option/keys.editor
*/
- public function keysEditor($value)
+ public function keysEditor(string $value): static
{
- $this->attributes['keys']['editor'] = $value;
-
- return $this;
+ return $this->keys(['editor' => $value]);
}
/**
* Set keys editorKeys option value.
*
- * @param mixed $value
* @return $this
+ *
* @see https://datatables.net/reference/option/keys.editorKeys
*/
- public function keysEditorKeys($value = 'navigation-only')
+ public function keysEditorKeys(string $value = 'navigation-only'): static
{
- $this->attributes['keys']['editorKeys'] = $value;
-
- return $this;
+ return $this->keys(['editorKeys' => $value]);
}
/**
* Set keys focus option value.
*
- * @param string $value
* @return $this
+ *
* @see https://datatables.net/reference/option/keys.focus
*/
- public function keysFocus($value)
+ public function keysFocus(string $value): static
{
- $this->attributes['keys']['focus'] = $value;
-
- return $this;
+ return $this->keys(['focus' => $value]);
}
/**
- * Set keys keys option value.
+ * Set key's keys option value.
*
- * @param mixed $value
* @return $this
+ *
* @see https://datatables.net/reference/option/keys.keys
*/
- public function keysKeys($value)
+ public function keysKeys(?array $value = null): static
{
- $this->attributes['keys']['keys'] = $value;
-
- return $this;
+ return $this->keys(['keys' => $value]);
}
/**
* Set keys tabIndex option value.
*
- * @param mixed $value
* @return $this
+ *
* @see https://datatables.net/reference/option/keys.tabIndex
*/
- public function keysTabIndex($value)
+ public function keysTabIndex(int $value): static
+ {
+ return $this->keys(['tabIndex' => $value]);
+ }
+
+ public function getKeys(?string $key = null): mixed
{
- $this->attributes['keys']['tabIndex'] = $value;
+ if (is_null($key)) {
+ return $this->attributes['keys'] ?? true;
+ }
- return $this;
+ return $this->attributes['keys'][$key] ?? false;
}
}
diff --git a/src/Html/Options/Plugins/Responsive.php b/src/Html/Options/Plugins/Responsive.php
index afd678d..d5fd11a 100644
--- a/src/Html/Options/Plugins/Responsive.php
+++ b/src/Html/Options/Plugins/Responsive.php
@@ -12,114 +12,114 @@
trait Responsive
{
/**
- * Set responsive option value.
+ * Set responsive breakpoints option value.
*
- * @param bool|array $value
* @return $this
- * @see https://datatables.net/reference/option/responsive
+ *
+ * @see https://datatables.net/reference/option/responsive.breakpoints
*/
- public function responsive($value = true)
+ public function responsiveBreakpoints(array $value): static
{
- $this->attributes['responsive'] = $value;
-
- return $this;
+ return $this->responsive(['breakpoints' => $value]);
}
/**
- * Set responsive breakpoints option value.
+ * Set responsive option value.
*
- * @param mixed $value
* @return $this
- * @see https://datatables.net/reference/option/responsive.breakpoints
+ *
+ * @see https://datatables.net/reference/option/responsive
*/
- public function responsiveBreakpoints($value)
+ public function responsive(array|bool $value = true): static
{
- $this->attributes['responsive']['breakpoints'] = $value;
-
- return $this;
+ return $this->setPluginAttribute('responsive', $value);
}
/**
- * Set responsive details option value.
+ * Set responsive details display option value.
*
- * @param mixed $value
* @return $this
- * @see https://datatables.net/reference/option/responsive.details
+ *
+ * @see https://datatables.net/reference/option/responsive.details.display
*/
- public function responsiveDetails($value)
+ public function responsiveDetailsDisplay(array|string $value): static
{
- $this->attributes['responsive']['details'] = $value;
-
- return $this;
+ return $this->responsiveDetails(['display' => $value]);
}
/**
- * Set responsive details display option value.
+ * Set responsive details option value.
*
- * @param mixed $value
* @return $this
- * @see https://datatables.net/reference/option/responsive.details.display
+ *
+ * @see https://datatables.net/reference/option/responsive.details
*/
- public function responsiveDetailsDisplay($value)
+ public function responsiveDetails(bool|array $value): static
{
- $this->attributes['responsive']['details']['display'] = $value;
-
- return $this;
+ $responsive = (array) $this->getResponsive();
+ if (is_array($value)) {
+ $responsive['details'] = array_merge((array) ($responsive['details'] ?? []), $value);
+ } else {
+ $responsive['details'] = $value;
+ }
+
+ return $this->responsive($responsive);
}
/**
* Set responsive details renderer option value.
*
- * @param mixed $value
* @return $this
+ *
* @see https://datatables.net/reference/option/responsive.details.renderer
*/
- public function responsiveDetailsRenderer($value)
+ public function responsiveDetailsRenderer(string $value): static
{
- $this->attributes['responsive']['details']['renderer'] = $value;
-
- return $this;
+ return $this->responsiveDetails(['renderer' => $value]);
}
/**
* Set responsive details target option value.
*
- * @param mixed $value
* @return $this
+ *
* @see https://datatables.net/reference/option/responsive.details.target
*/
- public function responsiveDetailsTarget($value)
+ public function responsiveDetailsTarget(int|string $value): static
{
- $this->attributes['responsive']['details']['target'] = $value;
-
- return $this;
+ return $this->responsiveDetails(['target' => $value]);
}
/**
* Set responsive details type option value.
*
- * @param mixed $value
* @return $this
+ *
* @see https://datatables.net/reference/option/responsive.details.type
*/
- public function responsiveDetailsType($value)
+ public function responsiveDetailsType(string $value): static
{
- $this->attributes['responsive']['details']['type'] = $value;
-
- return $this;
+ return $this->responsiveDetails(['type' => $value]);
}
/**
* Set responsive orthogonal option value.
*
- * @param mixed $value
* @return $this
+ *
* @see https://datatables.net/reference/option/responsive.orthogonal
*/
- public function responsiveOrthogonal($value)
+ public function responsiveOrthogonal(string $value): static
+ {
+ return $this->responsive(['orthogonal' => $value]);
+ }
+
+ public function getResponsive(?string $key = null): mixed
{
- $this->attributes['responsive']['orthogonal'] = $value;
+ if (is_null($key)) {
+ return $this->attributes['responsive'] ?? true;
+ }
- return $this;
+ return $this->attributes['responsive'][$key] ?? false;
}
}
diff --git a/src/Html/Options/Plugins/RowGroup.php b/src/Html/Options/Plugins/RowGroup.php
index 2d41e51..cca6da3 100644
--- a/src/Html/Options/Plugins/RowGroup.php
+++ b/src/Html/Options/Plugins/RowGroup.php
@@ -12,128 +12,119 @@
trait RowGroup
{
/**
- * Set rowGroup option value.
+ * Set rowGroup className option value.
*
- * @param bool|array $value
* @return $this
- * @see https://datatables.net/reference/option/rowGroup
+ *
+ * @see https://datatables.net/reference/option/rowGroup.className
*/
- public function rowGroup($value = true)
+ public function rowGroupUpdate(string $value = 'group'): static
{
- $this->attributes['rowGroup'] = $value;
-
- return $this;
+ return $this->rowGroup(['className' => $value]);
}
/**
- * Set rowGroup className option value.
+ * Set rowGroup option value.
*
- * @param string $value
* @return $this
- * @see https://datatables.net/reference/option/rowGroup.className
+ *
+ * @see https://datatables.net/reference/option/rowGroup
*/
- public function rowGroupUpdate($value = 'group')
+ public function rowGroup(array|bool $value = true): static
{
- $this->attributes['rowGroup']['className'] = $value;
-
- return $this;
+ return $this->setPluginAttribute('rowGroup', $value);
}
/**
* Set rowGroup dataSrc option value.
*
- * @param mixed $value
* @return $this
+ *
* @see https://datatables.net/reference/option/rowGroup.dataSrc
*/
- public function rowGroupDataSrc($value = 0)
+ public function rowGroupDataSrc(array|int|string $value = 0): static
{
- $this->attributes['rowGroup']['dataSrc'] = $value;
-
- return $this;
+ return $this->rowGroup(['dataSrc' => $value]);
}
/**
* Set rowGroup emptyDataGroup option value.
*
- * @param mixed $value
* @return $this
+ *
* @see https://datatables.net/reference/option/rowGroup.emptyDataGroup
*/
- public function rowGroupEmptyDataGroup($value = 'No Group')
+ public function rowGroupEmptyDataGroup(string $value = 'No Group'): static
{
- $this->attributes['rowGroup']['emptyDataGroup'] = $value;
-
- return $this;
+ return $this->rowGroup(['emptyDataGroup' => $value]);
}
/**
* Set rowGroup enable option value.
*
- * @param bool $value
* @return $this
+ *
* @see https://datatables.net/reference/option/rowGroup.enable
*/
- public function rowGroupEnable(bool $value = true)
+ public function rowGroupEnable(bool $value = true): static
{
- $this->attributes['rowGroup']['enable'] = $value;
-
- return $this;
+ return $this->rowGroup(['enable' => $value]);
}
/**
* Set rowGroup endClassName option value.
*
- * @param mixed $value
* @return $this
+ *
* @see https://datatables.net/reference/option/rowGroup.endClassName
*/
- public function rowGroupEndClassName($value = 'group-end')
+ public function rowGroupEndClassName(string $value = 'group-end'): static
{
- $this->attributes['rowGroup']['endClassName'] = $value;
-
- return $this;
+ return $this->rowGroup(['endClassName' => $value]);
}
/**
* Set rowGroup endRender option value.
*
- * @param mixed $value
* @return $this
+ *
* @see https://datatables.net/reference/option/rowGroup.endRender
*/
- public function rowGroupEndRender($value)
+ public function rowGroupEndRender(string $value): static
{
- $this->attributes['rowGroup']['endRender'] = $value;
-
- return $this;
+ return $this->rowGroup(['endRender' => $value]);
}
/**
* Set rowGroup startClassName option value.
*
- * @param mixed $value
* @return $this
+ *
* @see https://datatables.net/reference/option/rowGroup.startClassName
*/
- public function rowGroupStartClassName($value = 'group-start')
+ public function rowGroupStartClassName(string $value = 'group-start'): static
{
- $this->attributes['rowGroup']['startClassName'] = $value;
-
- return $this;
+ return $this->rowGroup(['startClassName' => $value]);
}
/**
* Set rowGroup startRender option value.
*
- * @param mixed $value
* @return $this
+ *
* @see https://datatables.net/reference/option/rowGroup.startRender
*/
- public function rowGroupStartRender($value)
+ public function rowGroupStartRender(?string $value = null): static
+ {
+ return $this->rowGroup(['startRender' => $value]);
+ }
+
+ public function getRowGroup(?string $key = null): mixed
{
- $this->attributes['rowGroup']['startRender'] = $value;
+ if (is_null($key)) {
+ return $this->attributes['rowGroup'] ?? true;
+ }
- return $this;
+ return $this->attributes['rowGroup'][$key] ?? false;
}
}
diff --git a/src/Html/Options/Plugins/RowReorder.php b/src/Html/Options/Plugins/RowReorder.php
index d4050a6..262533c 100644
--- a/src/Html/Options/Plugins/RowReorder.php
+++ b/src/Html/Options/Plugins/RowReorder.php
@@ -12,114 +12,107 @@
trait RowReorder
{
/**
- * Set rowReorder option value.
+ * Set rowReorder dataSrc option value.
*
- * @param bool|array $value
* @return $this
- * @see https://datatables.net/reference/option/rowReorder
+ *
+ * @see https://datatables.net/reference/option/rowReorder.dataSrc
*/
- public function rowReorder($value = true)
+ public function rowReorderDataSrc(array|int $value = 0): static
{
- $this->attributes['rowReorder'] = $value;
-
- return $this;
+ return $this->rowReorder(['dataSrc' => $value]);
}
/**
- * Set rowReorder dataSrc option value.
+ * Set rowReorder option value.
*
- * @param mixed $value
* @return $this
- * @see https://datatables.net/reference/option/rowReorder.dataSrc
+ *
+ * @see https://datatables.net/reference/option/rowReorder
*/
- public function rowReorderDataSrc($value = 0)
+ public function rowReorder(array|bool $value = true): static
{
- $this->attributes['rowReorder']['dataSrc'] = $value;
-
- return $this;
+ return $this->setPluginAttribute('rowReorder', $value);
}
/**
* Set rowReorder editor option value.
*
- * @param mixed $value
* @return $this
+ *
* @see https://datatables.net/reference/option/rowReorder.editor
*/
- public function rowReorderEditor($value = null)
+ public function rowReorderEditor(?string $value = null): static
{
- $this->attributes['rowReorder']['editor'] = $value;
-
- return $this;
+ return $this->rowReorder(['editor' => $value]);
}
/**
* Set rowReorder enable option value.
*
- * @param bool $value
* @return $this
+ *
* @see https://datatables.net/reference/option/rowReorder.enable
*/
- public function rowReorderEnable(bool $value = true)
+ public function rowReorderEnable(bool $value = true): static
{
- $this->attributes['rowReorder']['enable'] = $value;
-
- return $this;
+ return $this->rowReorder(['enable' => $value]);
}
/**
* Set rowReorder formOptions option value.
*
- * @param mixed $value
* @return $this
+ *
* @see https://datatables.net/reference/option/rowReorder.formOptions
*/
- public function rowReorderFormOptions($value)
+ public function rowReorderFormOptions(array $value): static
{
- $this->attributes['rowReorder']['formOptions'] = $value;
-
- return $this;
+ return $this->rowReorder(['formOptions' => $value]);
}
/**
* Set rowReorder selector option value.
*
- * @param string $value
* @return $this
+ *
* @see https://datatables.net/reference/option/rowReorder.selector
*/
- public function rowReorderSelector($value = 'td:first-child')
+ public function rowReorderSelector(string $value = 'td:first-child'): static
{
- $this->attributes['rowReorder']['selector'] = $value;
-
- return $this;
+ return $this->rowReorder(['selector' => $value]);
}
/**
* Set rowReorder snapX option value.
*
- * @param mixed $value
* @return $this
+ *
* @see https://datatables.net/reference/option/rowReorder.snapX
*/
- public function rowReorderSnapX($value = true)
+ public function rowReorderSnapX(bool|int $value = true): static
{
- $this->attributes['rowReorder']['snapX'] = $value;
-
- return $this;
+ return $this->rowReorder(['snapX' => $value]);
}
/**
* Set rowReorder update option value.
*
- * @param bool $value
* @return $this
+ *
* @see https://datatables.net/reference/option/rowReorder.update
*/
- public function rowReorderUpdate(bool $value = true)
+ public function rowReorderUpdate(bool $value = true): static
+ {
+ return $this->rowReorder(['update' => $value]);
+ }
+
+ public function getRowReorder(?string $key = null): mixed
{
- $this->attributes['rowReorder']['update'] = $value;
+ if (is_null($key)) {
+ return $this->attributes['rowReorder'] ?? true;
+ }
- return $this;
+ return $this->attributes['rowReorder'][$key] ?? false;
}
}
diff --git a/src/Html/Options/Plugins/Scroller.php b/src/Html/Options/Plugins/Scroller.php
index 37b4ce3..96d23bf 100644
--- a/src/Html/Options/Plugins/Scroller.php
+++ b/src/Html/Options/Plugins/Scroller.php
@@ -12,86 +12,83 @@
trait Scroller
{
/**
- * Set scroller option value.
+ * Set scroller boundaryScale option value.
*
- * @param bool|array $value
* @return $this
- * @see https://datatables.net/reference/option/scroller
+ *
+ * @see https://datatables.net/reference/option/scroller.boundaryScale
*/
- public function scroller($value = true)
+ public function scrollerBoundaryScale(float $value = 0.5): static
{
- $this->attributes['scroller'] = $value;
-
- return $this;
+ return $this->scroller(['boundaryScale' => $value]);
}
/**
- * Set scroller boundaryScale option value.
+ * Set scroller option value.
*
- * @param float $value
* @return $this
- * @see https://datatables.net/reference/option/scroller.boundaryScale
+ *
+ * @see https://datatables.net/reference/option/scroller
*/
- public function scrollerBoundaryScale($value = 0.5)
+ public function scroller(array|bool $value = true): static
{
- $this->attributes['scroller']['boundaryScale'] = $value;
-
- return $this;
+ return $this->setPluginAttribute('scroller', $value);
}
/**
* Set scroller displayBuffer option value.
*
- * @param int $value
* @return $this
+ *
* @see https://datatables.net/reference/option/scroller.displayBuffer
*/
- public function scrollerDisplayBuffer($value = 9)
+ public function scrollerDisplayBuffer(int $value = 9): static
{
- $this->attributes['scroller']['displayBuffer'] = $value;
-
- return $this;
+ return $this->scroller(['displayBuffer' => $value]);
}
/**
* Set scroller loadingIndicator option value.
*
- * @param bool $value
* @return $this
+ *
* @see https://datatables.net/reference/option/scroller.loadingIndicator
*/
- public function scrollerLoadingIndicator(bool $value = true)
+ public function scrollerLoadingIndicator(bool $value = true): static
{
- $this->attributes['scroller']['loadingIndicator'] = $value;
-
- return $this;
+ return $this->scroller(['loadingIndicator' => $value]);
}
/**
* Set scroller rowHeight option value.
*
- * @param int|string $value
* @return $this
+ *
* @see https://datatables.net/reference/option/scroller.rowHeight
*/
- public function scrollerRowHeight($value = 'auto')
+ public function scrollerRowHeight(int|string $value = 'auto'): static
{
- $this->attributes['scroller']['rowHeight'] = $value;
-
- return $this;
+ return $this->scroller(['rowHeight' => $value]);
}
/**
* Set scroller serverWait option value.
*
- * @param int $value
* @return $this
+ *
* @see https://datatables.net/reference/option/scroller.serverWait
*/
- public function scrollerServerWait($value = 200)
+ public function scrollerServerWait(int $value = 200): static
+ {
+ return $this->scroller(['serverWait' => $value]);
+ }
+
+ public function getScroller(?string $key = null): mixed
{
- $this->attributes['scroller']['serverWait'] = $value;
+ if (is_null($key)) {
+ return $this->attributes['scroller'] ?? true;
+ }
- return $this;
+ return $this->attributes['scroller'][$key] ?? false;
}
}
diff --git a/src/Html/Options/Plugins/SearchPanes.php b/src/Html/Options/Plugins/SearchPanes.php
index 5b966c3..5bd95cb 100644
--- a/src/Html/Options/Plugins/SearchPanes.php
+++ b/src/Html/Options/Plugins/SearchPanes.php
@@ -2,8 +2,8 @@
namespace Yajra\DataTables\Html\Options\Plugins;
-use Yajra\DataTables\Html\SearchPane;
use Illuminate\Contracts\Support\Arrayable;
+use Yajra\DataTables\Html\SearchPane;
/**
* DataTables - Search panes plugin option builder.
@@ -16,11 +16,11 @@ trait SearchPanes
/**
* Set searchPane option value.
*
- * @param bool|array $value
* @return $this
+ *
* @see https://datatables.net/reference/option/searchPanes
*/
- public function searchPanes($value = true)
+ public function searchPanes(array|Arrayable|bool|callable $value = true): static
{
if (is_callable($value)) {
$value = app()->call($value);
@@ -38,4 +38,13 @@ public function searchPanes($value = true)
return $this;
}
+
+ public function getSearchPanes(?string $key = null): mixed
+ {
+ if (is_null($key)) {
+ return $this->attributes['searchPanes'] ?? true;
+ }
+
+ return $this->attributes['searchPanes'][$key] ?? false;
+ }
}
diff --git a/src/Html/Options/Plugins/Select.php b/src/Html/Options/Plugins/Select.php
index ac971c8..056d8e6 100644
--- a/src/Html/Options/Plugins/Select.php
+++ b/src/Html/Options/Plugins/Select.php
@@ -12,221 +12,220 @@
*/
trait Select
{
- /**
- * Set select option value.
- *
- * @param bool|array $value
- * @return $this
- * @see https://datatables.net/reference/option/select
- */
- public function select($value = true)
- {
- $this->attributes['select'] = $value;
-
- return $this;
- }
-
/**
* Set select blurable option value.
*
- * @param bool $value
* @return $this
+ *
* @see https://datatables.net/reference/option/select.blurable
*/
- public function selectBlurable(bool $value = true)
+ public function selectBlurable(bool $value = true): static
{
- $this->attributes['select']['blurable'] = $value;
-
- return $this;
+ return $this->select(['blurable' => $value]);
}
/**
* Set select className option value.
*
- * @param string $value
* @return $this
+ *
* @see https://datatables.net/reference/option/select.className
*/
- public function selectClassName($value = 'selected')
+ public function selectClassName(string $value = 'selected'): static
{
- $this->attributes['select']['className'] = $value;
-
- return $this;
+ return $this->select(['className' => $value]);
}
/**
* Append a class name to className option value.
*
- * @param string $class
* @return $this
*/
- public function selectAddClassName($class)
+ public function selectAddClassName(string $class): static
{
if (! isset($this->attributes['select']['className'])) {
$this->attributes['select']['className'] = $class;
} else {
$this->attributes['select']['className'] .= " $class";
}
+
return $this;
}
/**
* Set select info option value.
*
- * @param bool $value
* @return $this
+ *
* @see https://datatables.net/reference/option/select.info
*/
- public function selectInfo(bool $value = true)
+ public function selectInfo(bool $value = true): static
{
- $this->attributes['select']['info'] = $value;
-
- return $this;
+ return $this->select(['info' => $value]);
}
/**
* Set select items option value.
*
- * @param string $value
* @return $this
+ *
* @see https://datatables.net/reference/option/select.items
*/
- public function selectItems($value = 'row')
+ public function selectItems(string $value = 'row'): static
{
- $this->attributes['select']['items'] = $value;
-
- return $this;
+ return $this->select(['items' => $value]);
}
/**
* Set select items option value to row.
*
* @return $this
+ *
* @see https://datatables.net/reference/option/select.items
*/
- public function selectItemsRow()
+ public function selectItemsRow(): static
{
- $this->attributes['select']['items'] = Builder::SELECT_ITEMS_ROW;
-
- return $this;
+ return $this->select(['items' => Builder::SELECT_ITEMS_ROW]);
}
/**
* Set select items option value to column.
*
* @return $this
+ *
* @see https://datatables.net/reference/option/select.items
*/
- public function selectItemsColumn()
+ public function selectItemsColumn(): static
{
- $this->attributes['select']['items'] = Builder::SELECT_ITEMS_COLUMN;
-
- return $this;
+ return $this->select(['items' => Builder::SELECT_ITEMS_COLUMN]);
}
/**
* Set select items option value to cell.
*
* @return $this
+ *
* @see https://datatables.net/reference/option/select.items
*/
- public function selectItemsCell()
+ public function selectItemsCell(): static
{
- $this->attributes['select']['items'] = Builder::SELECT_ITEMS_CELL;
-
- return $this;
+ return $this->select(['items' => Builder::SELECT_ITEMS_CELL]);
}
/**
* Set select selector option value.
*
- * @param string $value
* @return $this
+ *
* @see https://datatables.net/reference/option/select.selector
*/
- public function selectSelector($value = 'td')
+ public function selectSelector(string $value = 'td'): static
{
- $this->attributes['select']['selector'] = $value;
-
- return $this;
+ return $this->select(['selector' => $value]);
}
/**
* Set select style option value.
*
- * @param string $value
* @return $this
+ *
* @see https://datatables.net/reference/option/select.style
*/
- public function selectStyle($value = 'os')
+ public function selectStyle(string $value = 'os'): static
{
- $this->attributes['select']['style'] = $value;
-
- return $this;
+ return $this->select(['style' => $value]);
}
/**
* Set select style option value to api.
*
* @return $this
+ *
* @see https://datatables.net/reference/option/select.style
*/
- public function selectStyleApi()
+ public function selectStyleApi(): static
{
- $this->attributes['select']['style'] = Builder::SELECT_STYLE_API;
-
- return $this;
+ return $this->select(['style' => Builder::SELECT_STYLE_API]);
}
/**
* Set select style option value to single.
*
* @return $this
+ *
* @see https://datatables.net/reference/option/select.style
*/
- public function selectStyleSingle()
+ public function selectStyleSingle(): static
{
- $this->attributes['select']['style'] = Builder::SELECT_STYLE_SINGLE;
+ return $this->select(['style' => Builder::SELECT_STYLE_SINGLE]);
+ }
- return $this;
+ /**
+ * Set select option value.
+ *
+ * @return $this
+ *
+ * @see https://datatables.net/reference/option/select
+ */
+ public function select(bool|array $value = true): static
+ {
+ return $this->setPluginAttribute('select', $value);
}
/**
* Set select style option value to multi.
*
* @return $this
+ *
* @see https://datatables.net/reference/option/select.style
*/
- public function selectStyleMulti()
+ public function selectStyleMulti(): static
{
- $this->attributes['select']['style'] = Builder::SELECT_STYLE_MULTI;
-
- return $this;
+ return $this->select(['style' => Builder::SELECT_STYLE_MULTI]);
}
/**
* Set select style option value to os.
*
* @return $this
+ *
* @see https://datatables.net/reference/option/select.style
*/
- public function selectStyleOS()
+ public function selectStyleOS(): static
{
- $this->attributes['select']['style'] = Builder::SELECT_STYLE_OS;
-
- return $this;
+ return $this->select(['style' => Builder::SELECT_STYLE_OS]);
}
/**
* Set select style option value to multi+shift.
*
* @return $this
+ *
* @see https://datatables.net/reference/option/select.style
*/
- public function selectStyleMultiShift()
+ public function selectStyleMultiShift(): static
{
- $this->attributes['select']['style'] = Builder::SELECT_STYLE_MULTI_SHIFT;
+ return $this->select(['style' => Builder::SELECT_STYLE_MULTI_SHIFT]);
+ }
- return $this;
+ /**
+ * Select keyboard navigation and selection.
+ *
+ * @return $this
+ *
+ * @see https://datatables.net/extensions/select/examples/initialisation/keys
+ */
+ public function selectKeys(bool $enabled = true): static
+ {
+ return $this->select(['keys' => $enabled]);
+ }
+
+ public function getSelect(?string $key = null): mixed
+ {
+ if (is_null($key)) {
+ return $this->attributes['select'] ?? true;
+ }
+
+ return $this->attributes['select'][$key] ?? false;
}
}
diff --git a/src/Html/Parameters.php b/src/Html/Parameters.php
index ca93fba..4d3faee 100644
--- a/src/Html/Parameters.php
+++ b/src/Html/Parameters.php
@@ -2,18 +2,10 @@
namespace Yajra\DataTables\Html;
-use Illuminate\Support\Fluent;
-
-/**
- * @property bool serverSide
- * @property bool processing
- * @property mixed ajax
- * @property array columns
- */
class Parameters extends Fluent
{
/**
- * @var array
+ * @var array
*/
protected $attributes = [
'serverSide' => true,
diff --git a/src/Html/SearchPane.php b/src/Html/SearchPane.php
index 7b2a0bc..da90b11 100644
--- a/src/Html/SearchPane.php
+++ b/src/Html/SearchPane.php
@@ -2,27 +2,29 @@
namespace Yajra\DataTables\Html;
-use Illuminate\Support\Fluent;
+use Closure;
use Illuminate\Contracts\Support\Arrayable;
+use Illuminate\Database\Eloquent\Builder as EloquentBuilder;
use Yajra\DataTables\Html\Editor\Fields\Options;
class SearchPane extends Fluent
{
- /**
- * @param array $options
- * @return static
- */
- public static function make(array $options = [])
+ public function __construct($attributes = [])
+ {
+ parent::__construct(['show' => true] + $attributes);
+ }
+
+ public static function make(array $options = []): static
{
return new static($options);
}
/**
- * @param bool $value
- * @return static
+ * @return $this
+ *
* @see https://datatables.net/reference/option/searchPanes.cascadePanes
*/
- public function cascadePanes($value = true)
+ public function cascadePanes(bool $value = true): static
{
$this->attributes['cascadePanes'] = $value;
@@ -30,11 +32,11 @@ public function cascadePanes($value = true)
}
/**
- * @param bool $value
- * @return static
+ * @return $this
+ *
* @see https://datatables.net/reference/option/searchPanes.clear
*/
- public function clear($value = true)
+ public function clear(bool $value = true): static
{
$this->attributes['clear'] = $value;
@@ -42,11 +44,11 @@ public function clear($value = true)
}
/**
- * @param array $value
- * @return static
+ * @return $this
+ *
* @see https://datatables.net/reference/option/searchPanes.columns
*/
- public function columns(array $value = [])
+ public function columns(array $value = []): static
{
$this->attributes['columns'] = $value;
@@ -54,11 +56,11 @@ public function columns(array $value = [])
}
/**
- * @param bool $value
- * @return static
+ * @return $this
+ *
* @see https://datatables.net/reference/option/searchPanes.controls
*/
- public function controls($value = true)
+ public function controls(bool $value = true): static
{
$this->attributes['controls'] = $value;
@@ -66,12 +68,12 @@ public function controls($value = true)
}
/**
- * @param array $value
- * @return static
+ * @return $this
+ *
* @see https://datatables.net/reference/option/searchPanes.dtOpts
* @see https://datatables.net/reference/option/columns.searchPanes.dtOpts
*/
- public function dtOpts(array $value = [])
+ public function dtOpts(array $value = []): static
{
$this->attributes['dtOpts'] = $value;
@@ -79,11 +81,11 @@ public function dtOpts(array $value = [])
}
/**
- * @param mixed $value
- * @return static
+ * @return $this
+ *
* @see https://datatables.net/reference/option/searchPanes.emptyMessage
*/
- public function emptyMessage($value)
+ public function emptyMessage(string $value): static
{
$this->attributes['emptyMessage'] = $value;
@@ -91,11 +93,11 @@ public function emptyMessage($value)
}
/**
- * @param mixed $value
- * @return static
+ * @return $this
+ *
* @see https://datatables.net/reference/option/searchPanes.filterChanged
*/
- public function filterChanged($value)
+ public function filterChanged(string $value): static
{
$this->attributes['filterChanged'] = $value;
@@ -103,11 +105,11 @@ public function filterChanged($value)
}
/**
- * @param bool $value
- * @return static
+ * @return $this
+ *
* @see https://datatables.net/reference/option/searchPanes.hideCount
*/
- public function hideCount($value = true)
+ public function hideCount(bool $value = true): static
{
$this->attributes['hideCount'] = $value;
@@ -115,11 +117,11 @@ public function hideCount($value = true)
}
/**
- * @param mixed $value
- * @return static
+ * @return $this
+ *
* @see https://datatables.net/reference/option/searchPanes.layout
*/
- public function layout($value)
+ public function layout(string $value): static
{
$this->attributes['layout'] = $value;
@@ -127,11 +129,11 @@ public function layout($value)
}
/**
- * @param mixed $value
- * @return static
+ * @return $this
+ *
* @see https://datatables.net/reference/option/searchPanes.order
*/
- public function order($value)
+ public function order(array $value): static
{
$this->attributes['order'] = $value;
@@ -139,11 +141,11 @@ public function order($value)
}
/**
- * @param boolean $value
- * @return static
+ * @return $this
+ *
* @see https://datatables.net/reference/option/searchPanes.orderable
*/
- public function orderable($value = true)
+ public function orderable(bool $value = true): static
{
$this->attributes['orderable'] = $value;
@@ -151,11 +153,11 @@ public function orderable($value = true)
}
/**
- * @param array $value
- * @return static
+ * @return $this
+ *
* @see https://datatables.net/reference/option/searchPanes.panes
*/
- public function panes(array $value)
+ public function panes(array $value): static
{
$panes = collect($value)->map(function ($pane) {
if ($pane instanceof Arrayable) {
@@ -171,11 +173,11 @@ public function panes(array $value)
}
/**
- * @param mixed $value
- * @return static
+ * @return $this
+ *
* @see https://datatables.net/reference/option/searchPanes.threshold
*/
- public function threshold($value)
+ public function threshold(float $value): static
{
$this->attributes['threshold'] = $value;
@@ -183,11 +185,11 @@ public function threshold($value)
}
/**
- * @param boolean $value
- * @return static
+ * @return $this
+ *
* @see https://datatables.net/reference/option/searchPanes.viewTotal
*/
- public function viewTotal($value = true)
+ public function viewTotal(bool $value = true): static
{
$this->attributes['viewTotal'] = $value;
@@ -195,11 +197,11 @@ public function viewTotal($value = true)
}
/**
- * @param boolean $value
- * @return static
+ * @return $this
+ *
* @see https://datatables.net/reference/option/searchPanes.viewTotal
*/
- public function hideTotal($value = true)
+ public function hideTotal(bool $value = true): static
{
$this->attributes['viewTotal'] = ! $value;
@@ -209,24 +211,19 @@ public function hideTotal($value = true)
/**
* Get options from a model.
*
- * @param mixed $model
- * @param string $value
- * @param string $key
- * @return $this
+ * @param class-string<\Illuminate\Database\Eloquent\Model>|EloquentBuilder $model
*/
- public function modelOptions($model, $value, $key = 'id')
+ public function modelOptions(EloquentBuilder|string $model, string $value, string $key = 'id'): SearchPane
{
- return $this->options(
- Options::model($model, $value, $key)
- );
+ return $this->options(Options::model($model, $value, $key));
}
/**
- * @param mixed $value
- * @return static
+ * @return $this
+ *
* @see https://datatables.net/reference/option/columns.searchPanes.options
*/
- public function options($value)
+ public function options(array|Arrayable $value): static
{
if ($value instanceof Arrayable) {
$value = $value->toArray();
@@ -240,26 +237,24 @@ public function options($value)
/**
* Get options from a table.
*
- * @param mixed $table
- * @param string $value
- * @param string $key
- * @param \Closure $whereCallback
- * @param string|null $key
* @return $this
*/
- public function tableOptions($table, $value, $key = 'id', \Closure $whereCallback = null, $connection = null)
- {
- return $this->options(
- Options::table($table, $value, $key, $whereCallback, $connection)
- );
+ public function tableOptions(
+ string $table,
+ string $value,
+ string $key = 'id',
+ ?Closure $callback = null,
+ ?string $connection = null
+ ): static {
+ return $this->options(Options::table($table, $value, $key, $callback, $connection));
}
/**
- * @param mixed $value
- * @return static
+ * @return $this
+ *
* @see https://datatables.net/reference/option/columns.searchPanes.className
*/
- public function className($value)
+ public function className(string $value): static
{
$this->attributes['className'] = $value;
@@ -267,11 +262,11 @@ public function className($value)
}
/**
- * @param mixed $value
- * @return static
+ * @return $this
+ *
* @see https://datatables.net/reference/option/searchPanes.panes.header
*/
- public function header($value)
+ public function header(string $value): static
{
$this->attributes['header'] = $value;
@@ -279,11 +274,11 @@ public function header($value)
}
/**
- * @param bool $value
- * @return static
+ * @return $this
+ *
* @see https://datatables.net/reference/option/columns.searchPanes.show
*/
- public function show($value = true)
+ public function show(bool $value = true): static
{
$this->attributes['show'] = $value;
@@ -291,11 +286,11 @@ public function show($value = true)
}
/**
- * @param mixed $value
- * @return static
+ * @return $this
+ *
* @see https://datatables.net/reference/option/columns.searchPanes.name
*/
- public function name($value)
+ public function name(string $value): static
{
$this->attributes['name'] = $value;
@@ -303,14 +298,38 @@ public function name($value)
}
/**
- * @param mixed $value
- * @return static
+ * @return $this
+ *
* @see https://datatables.net/reference/option/columns.searchPanes.orthogonal
*/
- public function orthogonal($value)
+ public function orthogonal(array|string $value): static
{
$this->attributes['orthogonal'] = $value;
return $this;
}
+
+ /**
+ * @return $this
+ *
+ * @see https://datatables.net/reference/option/searchPanes.collapse
+ */
+ public function collapse(bool $value = true): static
+ {
+ $this->attributes['collapse'] = $value;
+
+ return $this;
+ }
+
+ /**
+ * @return $this
+ *
+ * @see https://datatables.net/reference/option/searchPanes.initCollapsed
+ */
+ public function initCollapsed(bool $value = false): static
+ {
+ $this->attributes['initCollapsed'] = $value;
+
+ return $this;
+ }
}
diff --git a/src/HtmlServiceProvider.php b/src/HtmlServiceProvider.php
index 343278b..b0de459 100644
--- a/src/HtmlServiceProvider.php
+++ b/src/HtmlServiceProvider.php
@@ -3,18 +3,15 @@
namespace Yajra\DataTables;
use Illuminate\Support\ServiceProvider;
-use Collective\Html\HtmlServiceProvider as CollectiveHtml;
class HtmlServiceProvider extends ServiceProvider
{
/**
* Bootstrap the application events.
- *
- * @return void
*/
- public function boot()
+ public function boot(): void
{
- $this->loadViewsFrom(__DIR__ . '/resources/views', 'datatables');
+ $this->loadViewsFrom(__DIR__.'/resources/views', 'datatables');
if ($this->app->runningInConsole()) {
$this->publishAssets();
@@ -24,27 +21,23 @@ public function boot()
/**
* Publish datatables assets.
*/
- protected function publishAssets()
+ protected function publishAssets(): void
{
$this->publishes([
- __DIR__ . '/resources/views' => base_path('/resources/views/vendor/datatables'),
- __DIR__ . '/resources/config/config.php' => config_path('datatables-html.php'),
+ __DIR__.'/resources/views' => base_path('/resources/views/vendor/datatables'),
+ __DIR__.'/resources/config/config.php' => config_path('datatables-html.php'),
], 'datatables-html');
}
/**
* Register the service provider.
- *
- * @return void
*/
- public function register()
+ public function register(): void
{
- $this->mergeConfigFrom(__DIR__ . '/resources/config/config.php', 'datatables-html');
+ $this->mergeConfigFrom(__DIR__.'/resources/config/config.php', 'datatables-html');
- $this->app->register(CollectiveHtml::class);
+ $this->app->bind('datatables.html', fn () => $this->app->make(Html\Builder::class));
- $this->app->bind('datatables.html', function () {
- return $this->app->make(Html\Builder::class);
- });
+ DataTables::macro('getHtmlBuilder', fn (): Html\Builder => app('datatables.html'));
}
}
diff --git a/src/resources/config/config.php b/src/resources/config/config.php
index 516d313..40a996a 100644
--- a/src/resources/config/config.php
+++ b/src/resources/config/config.php
@@ -12,15 +12,9 @@
*/
'table' => [
'class' => 'table',
- 'id' => 'dataTableBuilder',
+ 'id' => 'dataTableBuilder',
],
- /*
- * Default condition to determine if a parameter is a callback or not.
- * Callbacks needs to start by those terms or they will be casted to string.
- */
- 'callback' => ['$', '$.', 'function'],
-
/*
* Html builder script template.
*/
diff --git a/src/resources/views/editor.blade.php b/src/resources/views/editor.blade.php
index 3a464d5..3f274d4 100644
--- a/src/resources/views/editor.blade.php
+++ b/src/resources/views/editor.blade.php
@@ -1,4 +1,4 @@
-$(function(){
+document.addEventListener("DOMContentLoaded", function(){
window.{{ config('datatables-html.namespace', 'LaravelDataTables') }} = window.{{ config('datatables-html.namespace', 'LaravelDataTables') }} || {};
$.ajaxSetup({headers: {'X-CSRF-TOKEN': '{{csrf_token()}}'}});
@foreach($editors as $editor)
@@ -9,4 +9,7 @@
@endforeach
@endforeach
window.{{ config('datatables-html.namespace', 'LaravelDataTables') }}["%1$s"] = $("#%1$s").DataTable(%2$s);
-});
\ No newline at end of file
+});
+@foreach ($scripts as $script)
+@include($script)
+@endforeach
diff --git a/src/resources/views/functions/batch_remove.blade.php b/src/resources/views/functions/batch_remove.blade.php
new file mode 100644
index 0000000..192a7e5
--- /dev/null
+++ b/src/resources/views/functions/batch_remove.blade.php
@@ -0,0 +1,14 @@
+$(function(){
+ @foreach($editors as $editor)
+ {{ config('datatables-html.namespace', 'LaravelDataTables') }}["%1$s-{{$editor->instance}}"].on('preSubmit', function(e, data, action) {
+ if (action !== 'remove') return;
+
+ for (let row_id of Object.keys(data.data))
+ {
+ data.data[row_id] = {
+ DT_RowId: data.data[row_id].DT_RowId
+ };
+ }
+ });
+ @endforeach
+});
diff --git a/src/resources/views/scout.blade.php b/src/resources/views/scout.blade.php
new file mode 100644
index 0000000..506ad40
--- /dev/null
+++ b/src/resources/views/scout.blade.php
@@ -0,0 +1,23 @@
+$(function(){
+ $('#%1$s').on('xhr.dt', function (e, settings, json, xhr) {
+ if (json == null || !('disableOrdering' in json)) return;
+
+ let table = {{ config('datatables-html.namespace', 'LaravelDataTables') }}[$(this).attr('id')];
+ if (json.disableOrdering) {
+ table.settings()[0].aoColumns.forEach(function(column) {
+ column.bSortable = false;
+ $(column.nTh).removeClass('sorting_asc sorting_desc sorting').addClass('sorting_disabled');
+ });
+ } else {
+ let changed = false;
+ table.settings()[0].aoColumns.forEach(function(column) {
+ if (column.bSortable) return;
+ column.bSortable = true;
+ changed = true;
+ });
+ if (changed) {
+ table.draw();
+ }
+ }
+ });
+});
diff --git a/src/resources/views/script.blade.php b/src/resources/views/script.blade.php
index 82b3282..4d3b205 100644
--- a/src/resources/views/script.blade.php
+++ b/src/resources/views/script.blade.php
@@ -1 +1,4 @@
-$(function(){window.{{ config('datatables-html.namespace', 'LaravelDataTables') }}=window.{{ config('datatables-html.namespace', 'LaravelDataTables') }}||{};window.{{ config('datatables-html.namespace', 'LaravelDataTables') }}["%1$s"]=$("#%1$s").DataTable(%2$s);});
+document.addEventListener("DOMContentLoaded",function(){window.{{ config('datatables-html.namespace', 'LaravelDataTables') }}=window.{{ config('datatables-html.namespace', 'LaravelDataTables') }}||{};window.{{ config('datatables-html.namespace', 'LaravelDataTables') }}["%1$s"]=$("#%1$s").DataTable(%2$s);});
+@foreach ($scripts as $script)
+@include($script)
+@endforeach
diff --git a/tests/.gitkeep b/tests/.gitkeep
deleted file mode 100644
index e69de29..0000000
diff --git a/tests/Html/Builder/BuilderOptionsLanguageTest.php b/tests/Html/Builder/BuilderOptionsLanguageTest.php
new file mode 100644
index 0000000..9567d16
--- /dev/null
+++ b/tests/Html/Builder/BuilderOptionsLanguageTest.php
@@ -0,0 +1,113 @@
+getHtmlBuilder();
+ $builder->languageAria(['paginate' => ['first' => 'First']]);
+ $this->assertEquals(['paginate' => ['first' => 'First']], $builder->getLanguage('aria'));
+
+ $builder->languageAriaPaginate(['first' => 'First']);
+ $this->assertEquals(['first' => 'First'], $builder->getLanguage('aria')['paginate']);
+
+ $builder->languageAriaPaginateFirst('First');
+ $this->assertEquals('First', $builder->getLanguage('aria')['paginate']['first']);
+
+ $builder->languageAriaPaginateLast('Last');
+ $this->assertEquals('Last', $builder->getLanguage('aria')['paginate']['last']);
+
+ $builder->languageAriaPaginateNext('Next');
+ $this->assertEquals('Next', $builder->getLanguage('aria')['paginate']['next']);
+
+ $builder->languageAriaPaginatePrevious('Previous');
+ $this->assertEquals('Previous', $builder->getLanguage('aria')['paginate']['previous']);
+
+ $builder->languageAriaSortAscending('languageAriaSortAscending');
+ $this->assertEquals('languageAriaSortAscending', $builder->getLanguage('aria')['sortAscending']);
+
+ $builder->languageAriaSortDescending('languageAriaSortDescending');
+ $this->assertEquals('languageAriaSortDescending', $builder->getLanguage('aria')['sortDescending']);
+ }
+
+ #[Test]
+ public function it_has_language_autofill_options()
+ {
+ $builder = $this->getHtmlBuilder();
+ $builder->languageAutoFill(['button' => 'button']);
+ $this->assertEquals(['button' => 'button'], $builder->getLanguage('autoFill'));
+
+ $builder->languageAutoFillButton('button');
+ $this->assertEquals('button', $builder->getLanguage('autoFill')['button']);
+
+ $builder->languageAutoFillCancel('cancel');
+ $this->assertEquals('cancel', $builder->getLanguage('autoFill')['cancel']);
+
+ $builder->languageAutoFillFill('fill');
+ $this->assertEquals('fill', $builder->getLanguage('autoFill')['fill']);
+
+ $builder->languageAutoFillFillHorizontal('languageAutoFillFillHorizontal');
+ $this->assertEquals('languageAutoFillFillHorizontal', $builder->getLanguage('autoFill')['fillHorizontal']);
+
+ $builder->languageAutoFillFillVertical('languageAutoFillFillVertical');
+ $this->assertEquals('languageAutoFillFillVertical', $builder->getLanguage('autoFill')['fillVertical']);
+
+ $builder->languageAutoFillIncrement('languageAutoFillIncrement');
+ $this->assertEquals('languageAutoFillIncrement', $builder->getLanguage('autoFill')['increment']);
+
+ $builder->languageAutoFillInfo('languageAutoFillInfo');
+ $this->assertEquals('languageAutoFillInfo', $builder->getLanguage('autoFill')['info']);
+ }
+
+ #[Test]
+ public function it_has_language_paginate_options()
+ {
+ $builder = $this->getHtmlBuilder();
+ $builder->languagePaginate(['first' => 'First']);
+ $this->assertEquals(['first' => 'First'], $builder->getLanguage('paginate'));
+
+ $builder->languagePaginateFirst('languagePaginateFirst');
+ $this->assertEquals('languagePaginateFirst', $builder->getLanguage('paginate')['first']);
+
+ $builder->languagePaginateLast('languagePaginateLast');
+ $this->assertEquals('languagePaginateLast', $builder->getLanguage('paginate')['last']);
+
+ $builder->languagePaginateNext('languagePaginateNext');
+ $this->assertEquals('languagePaginateNext', $builder->getLanguage('paginate')['next']);
+
+ $builder->languagePaginatePrevious('languagePaginatePrevious');
+ $this->assertEquals('languagePaginatePrevious', $builder->getLanguage('paginate')['previous']);
+ }
+
+ #[Test]
+ public function it_has_language_select_options()
+ {
+ $builder = $this->getHtmlBuilder();
+ $builder->languageSelect(['cells' => 1]);
+ $this->assertEquals(['cells' => 1], $builder->getLanguage('select'));
+
+ $builder->languageSelectCells('languageSelectCells');
+ $this->assertEquals('languageSelectCells', $builder->getLanguage('select')['cells']);
+
+ $builder->languageSelectCells([1, 2, 3]);
+ $this->assertEquals([1, 2, 3], $builder->getLanguage('select')['cells']);
+
+ $builder->languageSelectColumns('languageSelectColumns');
+ $this->assertEquals('languageSelectColumns', $builder->getLanguage('select')['columns']);
+
+ $builder->languageSelectColumns([1, 2, 3]);
+ $this->assertEquals([1, 2, 3], $builder->getLanguage('select')['columns']);
+
+ $builder->languageSelectRows('languageSelectRows');
+ $this->assertEquals('languageSelectRows', $builder->getLanguage('select')['rows']);
+
+ $builder->languageSelectRows([1, 2, 3]);
+ $this->assertEquals([1, 2, 3], $builder->getLanguage('select')['rows']);
+ }
+}
diff --git a/tests/Html/Builder/BuilderOptionsPluginsTest.php b/tests/Html/Builder/BuilderOptionsPluginsTest.php
new file mode 100644
index 0000000..5c0e3e5
--- /dev/null
+++ b/tests/Html/Builder/BuilderOptionsPluginsTest.php
@@ -0,0 +1,334 @@
+getHtmlBuilder();
+
+ $this->assertTrue($builder->getAutoFill());
+
+ $builder->autoFill();
+ $this->assertTrue($builder->getAttribute('autoFill'));
+
+ $builder->autoFill(false);
+ $this->assertFalse($builder->getAttribute('autoFill'));
+
+ $builder->autoFillAlwaysAsk()
+ ->autoFillColumns('autoFillColumns')
+ ->autoFillEditor('autoFillEditor')
+ ->autoFillEnable()
+ ->autoFillFocus('autoFillFocus')
+ ->autoFillHorizontal()
+ ->autoFillUpdate()
+ ->autoFillVertical();
+
+ $this->assertTrue($builder->getAutoFill('alwaysAsk'));
+ $this->assertEquals('autoFillColumns', $builder->getAutoFill('columns'));
+ $this->assertEquals('autoFillEditor', $builder->getAutoFill('editor'));
+ $this->assertEquals(true, $builder->getAutoFill('enable'));
+ $this->assertEquals('autoFillFocus', $builder->getAutoFill('focus'));
+ $this->assertEquals(true, $builder->getAutoFill('horizontal'));
+ $this->assertEquals(true, $builder->getAutoFill('update'));
+ $this->assertEquals(true, $builder->getAutoFill('vertical'));
+
+ $builder->autoFillColumns([1, 2]);
+ $this->assertEquals([1, 2], $builder->getAutoFill('columns'));
+ }
+
+ #[Test]
+ public function it_has_buttons_plugin()
+ {
+ $builder = $this->getHtmlBuilder();
+ $builder->buttons(
+ Button::make('create'),
+ Button::make('edit'),
+ );
+
+ $this->assertCount(2, $builder->getAttribute('buttons'));
+ $this->assertCount(2, $builder->getButtons());
+ $this->assertIsArray($builder->getButtons()[0]);
+
+ $builder->buttons([Button::make('remove')]);
+ $this->assertCount(1, $builder->getButtons());
+
+ $builder->addButton(Button::make('edit'));
+ $this->assertCount(2, $builder->getButtons());
+ }
+
+ #[Test]
+ public function it_has_col_reorder_plugin()
+ {
+ $builder = $this->getHtmlBuilder();
+ $builder->colReorder();
+
+ $this->assertTrue($builder->getAttribute('colReorder'));
+ $this->assertTrue($builder->getColReorder());
+
+ $builder->colReorderEnable()
+ ->colReorderFixedColumnsLeft(1)
+ ->colReorderFixedColumnsRight(1)
+ ->colReorderOrder([1])
+ ->colReorderRealtime();
+
+ $this->assertTrue($builder->getColReorder('enable'));
+ $this->assertEquals(1, $builder->getColReorder('fixedColumnsLeft'));
+ $this->assertEquals(1, $builder->getColReorder('fixedColumnsRight'));
+ $this->assertEquals([1], $builder->getColReorder('order'));
+ $this->assertEquals(true, $builder->getColReorder('realtime'));
+ }
+
+ #[Test]
+ public function it_has_fixed_columns_plugin()
+ {
+ $builder = $this->getHtmlBuilder();
+ $builder->fixedColumns();
+
+ $this->assertTrue($builder->getAttribute('fixedColumns'));
+ $this->assertTrue($builder->getFixedColumns());
+
+ $builder->fixedColumnsHeightMatch()
+ ->fixedColumnsLeftColumns()
+ ->fixedColumnsRightColumns();
+
+ $this->assertEquals('semiauto', $builder->getFixedColumns('heightMatch'));
+ $this->assertEquals(1, $builder->getFixedColumns('leftColumns'));
+ $this->assertEquals(0, $builder->getFixedColumns('rightColumns'));
+ }
+
+ #[Test]
+ public function it_has_fixed_header_plugin()
+ {
+ $builder = $this->getHtmlBuilder();
+ $builder->fixedHeader();
+
+ $this->assertTrue($builder->getAttribute('fixedHeader'));
+ $this->assertTrue($builder->getFixedHeader());
+
+ $builder->fixedHeaderFooter()
+ ->fixedHeaderFooterOffset()
+ ->fixedHeaderHeader()
+ ->fixedHeaderHeaderOffset();
+
+ $this->assertEquals(true, $builder->getFixedHeader('footer'));
+ $this->assertEquals(0, $builder->getFixedHeader('offset'));
+ $this->assertEquals(true, $builder->getFixedHeader('header'));
+ $this->assertEquals(0, $builder->getFixedHeader('headerOffset'));
+ }
+
+ #[Test]
+ public function it_has_keys_plugin()
+ {
+
+ $builder = $this->getHtmlBuilder();
+ $builder->keys();
+
+ $this->assertTrue($builder->getAttribute('keys'));
+ $this->assertTrue($builder->getKeys());
+
+ $builder->keysBlurable()
+ ->keysClassName()
+ ->keysClipboard()
+ ->keysClipboardOrthogonal()
+ ->keysColumns('name')
+ ->keysEditAutoSelect()
+ ->keysEditOnFocus()
+ ->keysEditor('editor')
+ ->keysEditorKeys()
+ ->keysFocus(':eq(0)')
+ ->keysKeys(['charCodeAt(0)'])
+ ->keysTabIndex(1);
+
+ $this->assertEquals(true, $builder->getKeys('blurable'));
+ $this->assertEquals('focus', $builder->getKeys('className'));
+ $this->assertEquals(true, $builder->getKeys('clipboard'));
+ $this->assertEquals('display', $builder->getKeys('clipboardOrthogonal'));
+ $this->assertEquals('name', $builder->getKeys('columns'));
+ $this->assertEquals(true, $builder->getKeys('editAutoSelect'));
+ $this->assertEquals(true, $builder->getKeys('editOnFocus'));
+ $this->assertEquals('editor', $builder->getKeys('editor'));
+ $this->assertEquals('navigation-only', $builder->getKeys('editorKeys'));
+ $this->assertEquals(':eq(0)', $builder->getKeys('focus'));
+ $this->assertEquals(['charCodeAt(0)'], $builder->getKeys('keys'));
+ $this->assertEquals(1, $builder->getKeys('tabIndex'));
+ }
+
+ #[Test]
+ public function it_has_responsive_plugin()
+ {
+ $builder = $this->getHtmlBuilder();
+ $builder->responsive();
+
+ $this->assertTrue($builder->getAttribute('responsive'));
+ $this->assertTrue($builder->getResponsive());
+
+ $builder->responsiveBreakpoints([1])
+ ->responsiveDetailsDisplay('display')
+ ->responsiveDetailsRenderer('renderer')
+ ->responsiveDetailsTarget('target')
+ ->responsiveDetailsType('type')
+ ->responsiveOrthogonal('orthogonal');
+ $this->assertEquals([1], $builder->getResponsive('breakpoints'));
+ $this->assertEquals('display', $builder->getResponsive('details')['display']);
+ $this->assertEquals('renderer', $builder->getResponsive('details')['renderer']);
+ $this->assertEquals('target', $builder->getResponsive('details')['target']);
+ $this->assertEquals('type', $builder->getResponsive('details')['type']);
+ $this->assertEquals('orthogonal', $builder->getResponsive('orthogonal'));
+ }
+
+ #[Test]
+ public function it_has_row_group_plugin()
+ {
+ $builder = $this->getHtmlBuilder();
+ $builder->rowGroup();
+
+ $this->assertTrue($builder->getAttribute('rowGroup'));
+ $this->assertTrue($builder->getRowGroup());
+
+ $builder->rowGroupDataSrc([1])
+ ->rowGroupEmptyDataGroup()
+ ->rowGroupEnable()
+ ->rowGroupEndClassName()
+ ->rowGroupEndRender('fn')
+ ->rowGroupStartClassName()
+ ->rowGroupStartRender();
+
+ $this->assertEquals([1], $builder->getRowGroup('dataSrc'));
+ $this->assertEquals('No Group', $builder->getRowGroup('emptyDataGroup'));
+ $this->assertEquals(true, $builder->getRowGroup('enable'));
+ $this->assertEquals('group-end', $builder->getRowGroup('endClassName'));
+ $this->assertEquals('fn', $builder->getRowGroup('endRender'));
+ $this->assertEquals('group-start', $builder->getRowGroup('startClassName'));
+ $this->assertEquals(null, $builder->getRowGroup('startRender'));
+ }
+
+ #[Test]
+ public function it_has_row_reorder_plugin()
+ {
+ $builder = $this->getHtmlBuilder();
+ $builder->rowReorder();
+
+ $this->assertTrue($builder->getAttribute('rowReorder'));
+ $this->assertTrue($builder->getRowReorder());
+
+ $builder->rowReorderDataSrc([1])
+ ->rowReorderEditor('editor')
+ ->rowReorderEnable()
+ ->rowReorderFormOptions(['main' => []])
+ ->rowReorderSelector()
+ ->rowReorderSnapX()
+ ->rowReorderUpdate();
+
+ $this->assertEquals([1], $builder->getRowReorder('dataSrc'));
+ $this->assertEquals('editor', $builder->getRowReorder('editor'));
+ $this->assertEquals(true, $builder->getRowReorder('enable'));
+ $this->assertEquals(['main' => []], $builder->getRowReorder('formOptions'));
+ $this->assertEquals('td:first-child', $builder->getRowReorder('selector'));
+ $this->assertEquals(true, $builder->getRowReorder('snapX'));
+ $this->assertEquals(true, $builder->getRowReorder('update'));
+ }
+
+ #[Test]
+ public function it_has_scroller_plugin()
+ {
+ $builder = $this->getHtmlBuilder();
+ $builder->scroller();
+
+ $this->assertTrue($builder->getAttribute('scroller'));
+ $this->assertTrue($builder->getScroller());
+
+ $builder->scrollerBoundaryScale()
+ ->scrollerDisplayBuffer()
+ ->scrollerLoadingIndicator()
+ ->scrollerRowHeight()
+ ->scrollerServerWait();
+
+ $this->assertEquals(0.5, $builder->getScroller('boundaryScale'));
+ $this->assertEquals(9, $builder->getScroller('displayBuffer'));
+ $this->assertEquals(true, $builder->getScroller('loadingIndicator'));
+ $this->assertEquals('auto', $builder->getScroller('rowHeight'));
+ $this->assertEquals(200, $builder->getScroller('serverWait'));
+ }
+
+ #[Test]
+ public function it_has_search_panes_plugin()
+ {
+ $builder = $this->getHtmlBuilder();
+ $builder->searchPanes();
+
+ $this->assertEquals(['show' => true], $builder->getAttribute('searchPanes'));
+ $this->assertIsArray($builder->getSearchPanes());
+
+ $builder->searchPanes(false);
+ $this->assertEquals(['show' => false], $builder->getAttribute('searchPanes'));
+
+ $builder->searchPanes(['hide' => true]);
+ $this->assertEquals(['hide' => true], $builder->getAttribute('searchPanes'));
+
+ $builder->searchPanes(fn () => ['show' => true]);
+ $this->assertEquals(['show' => true], $builder->getAttribute('searchPanes'));
+
+ $builder->searchPanes(SearchPane::make()->show()->cascadePanes());
+ $this->assertEquals(['show' => true, 'cascadePanes' => true], $builder->getAttribute('searchPanes'));
+ }
+
+ #[Test]
+ public function it_has_select_plugin()
+ {
+ $builder = $this->getHtmlBuilder();
+ $builder->select();
+
+ $this->assertTrue($builder->getAttribute('select'));
+ $this->assertTrue($builder->getSelect());
+
+ $builder->selectBlurable()
+ ->selectClassName()
+ ->selectInfo()
+ ->selectItems()
+ ->selectSelector()
+ ->selectStyle();
+
+ $this->assertEquals(true, $builder->getSelect('blurable'));
+ $this->assertEquals('selected', $builder->getSelect('className'));
+ $this->assertEquals(true, $builder->getSelect('info'));
+ $this->assertEquals('row', $builder->getSelect('items'));
+ $this->assertEquals('td', $builder->getSelect('selector'));
+ $this->assertEquals('os', $builder->getSelect('style'));
+
+ $builder->selectAddClassName('test');
+ $this->assertEquals('selected test', $builder->getSelect('className'));
+
+ $builder->selectItemsRow();
+ $this->assertEquals(Builder::SELECT_ITEMS_ROW, $builder->getSelect('items'));
+
+ $builder->selectItemsColumn();
+ $this->assertEquals(Builder::SELECT_ITEMS_COLUMN, $builder->getSelect('items'));
+
+ $builder->selectItemsCell();
+ $this->assertEquals(Builder::SELECT_ITEMS_CELL, $builder->getSelect('items'));
+
+ $builder->selectStyleSingle();
+ $this->assertEquals(Builder::SELECT_STYLE_SINGLE, $builder->getSelect('style'));
+
+ $builder->selectStyleMulti();
+ $this->assertEquals(Builder::SELECT_STYLE_MULTI, $builder->getSelect('style'));
+
+ $builder->selectStyleOS();
+ $this->assertEquals(Builder::SELECT_STYLE_OS, $builder->getSelect('style'));
+
+ $builder->selectStyleMultiShift();
+ $this->assertEquals(Builder::SELECT_STYLE_MULTI_SHIFT, $builder->getSelect('style'));
+
+ $builder->selectStyleApi();
+ $this->assertEquals(Builder::SELECT_STYLE_API, $builder->getSelect('style'));
+ }
+}
diff --git a/tests/Html/Builder/BuilderOptionsTest.php b/tests/Html/Builder/BuilderOptionsTest.php
new file mode 100644
index 0000000..1d2ca0e
--- /dev/null
+++ b/tests/Html/Builder/BuilderOptionsTest.php
@@ -0,0 +1,287 @@
+getHtmlBuilder();
+
+ $builder
+ ->createdRow('function() {}')
+ ->drawCallback('function() {}')
+ ->footerCallback('function() {}')
+ ->formatNumber('function() {}')
+ ->headerCallback('function() {}')
+ ->infoCallback('function() {}')
+ ->initComplete('function() {}')
+ ->preDrawCallback('function() {}')
+ ->rowCallback('function() {}')
+ ->stateLoadCallback('function() {}')
+ ->stateLoaded('function() {}')
+ ->stateLoadParams('function() {}')
+ ->stateSaveCallback('function() {}')
+ ->stateSaveParams('function() {}');
+
+ $this->assertEquals('function() {}', $builder->getAttribute('createdRow'));
+ $this->assertEquals('function() {}', $builder->getAttribute('drawCallback'));
+ $this->assertEquals('function() {}', $builder->getAttribute('footerCallback'));
+ $this->assertEquals('function() {}', $builder->getAttribute('formatNumber'));
+ $this->assertEquals('function() {}', $builder->getAttribute('infoCallback'));
+ $this->assertEquals('function() {}', $builder->getAttribute('preDrawCallback'));
+ $this->assertEquals('function() {}', $builder->getAttribute('stateLoaded'));
+ $this->assertEquals('function() {}', $builder->getAttribute('stateSaveCallback'));
+ $this->assertEquals('function() {}', $builder->getAttribute('stateSaveParams'));
+
+ $builder->drawCallbackWithLivewire();
+ $this->assertStringContainsString('window.livewire.rescan()', $builder->getAttribute('drawCallback'));
+
+ $builder->drawCallbackWithLivewire('test livewire');
+ $this->assertStringContainsString('test livewire', $builder->getAttribute('drawCallback'));
+ }
+
+ #[Test]
+ public function it_has_columns_options()
+ {
+ $builder = $this->getHtmlBuilder();
+
+ $builder->columnDefs(['target' => [1]])
+ ->addColumnDef(['target' => [1]])
+ ->addColumnDef(['target' => [2]])
+ ->columns([
+ Column::make('id'),
+ Column::make('name'),
+ ]);
+
+ $this->assertEquals([1], $builder->getAttribute('columnDefs')['target']);
+ $this->assertEquals([1], $builder->getAttribute('columnDefs')[0]['target']);
+ $this->assertEquals([2], $builder->getAttribute('columnDefs')[1]['target']);
+ $this->assertCount(2, $builder->getColumns());
+ $this->assertInstanceOf(Column::class, $builder->getColumns()[0]);
+ $this->assertEquals('id', $builder->getColumns()[0]['data']);
+ $this->assertEquals('id', $builder->getColumns()[0]['name']);
+ $this->assertEquals('Id', $builder->getColumns()[0]['title']);
+
+ $builder->addColumn(['data' => 'email']);
+
+ $this->assertCount(3, $builder->getColumns());
+ $this->assertInstanceOf(Column::class, $builder->getColumns()[2]);
+ $this->assertEquals('email', $builder->getColumns()[2]['data']);
+ $this->assertEquals('email', $builder->getColumns()[2]['name']);
+ $this->assertEquals('Email', $builder->getColumns()[2]['title']);
+
+ $builder->addColumn(Column::make('created_at'));
+
+ $this->assertCount(4, $builder->getColumns());
+ $this->assertInstanceOf(Column::class, $builder->getColumns()[3]);
+ $this->assertEquals('created_at', $builder->getColumns()[3]['data']);
+ $this->assertEquals('created_at', $builder->getColumns()[3]['name']);
+ $this->assertEquals('Created At', $builder->getColumns()[3]['title']);
+
+ $builder->addColumnBefore(['data' => 'updated_at']);
+
+ $this->assertCount(5, $builder->getColumns());
+ $this->assertInstanceOf(Column::class, $builder->getColumns()[0]);
+ $this->assertEquals('updated_at', $builder->getColumns()[0]['data']);
+ $this->assertEquals('updated_at', $builder->getColumns()[0]['name']);
+ $this->assertEquals('Updated At', $builder->getColumns()[0]['title']);
+
+ $builder->addBefore(Column::make('deleted_at'));
+
+ $this->assertCount(6, $builder->getColumns());
+ $this->assertInstanceOf(Column::class, $builder->getColumns()[0]);
+ $this->assertEquals('deleted_at', $builder->getColumns()[0]['data']);
+ $this->assertEquals('deleted_at', $builder->getColumns()[0]['name']);
+ $this->assertEquals('Deleted At', $builder->getColumns()[0]['title']);
+
+ $builder->removeColumn('created_at', 'updated_at');
+ $this->assertCount(4, $builder->getColumns());
+ }
+
+ #[Test]
+ public function it_has_ajax_options()
+ {
+ $builder = $this->getHtmlBuilder();
+
+ $builder->postAjax('/test');
+
+ $this->assertEquals('/test', $builder->getAjaxUrl());
+ $this->assertEquals([
+ 'url' => '/test',
+ 'type' => 'POST',
+ 'headers' => [
+ 'X-HTTP-Method-Override' => 'GET',
+ ],
+ ], $builder->getAjax());
+
+ $builder->ajax('/test');
+ $this->assertEquals('/test', $builder->getAjaxUrl());
+
+ $builder->ajax(['url' => '/test']);
+ $this->assertEquals('/test', $builder->getAjax('url'));
+
+ $builder->pipeline('/test');
+ $this->assertEquals("$.fn.dataTable.pipeline({ url: '/test', pages: 5 })", $builder->getAjaxUrl());
+
+ $builder->pipeline('/test', 6);
+ $this->assertEquals("$.fn.dataTable.pipeline({ url: '/test', pages: 6 })", $builder->getAjaxUrl());
+
+ $builder->ajaxWithForm('/test', '#formId');
+ $this->assertStringContainsString('data.columns.length', $builder->getAjax()['data']);
+ $this->assertStringContainsString('delete data.columns[i].search;', $builder->getAjax('data'));
+ $this->assertStringContainsString('#formId', $builder->getAjax('data'));
+
+ $builder->minifiedAjax('/test', 'custom_script', ['id' => 123, 'name' => 'yajra']);
+ $this->assertEquals('/test', $builder->getAjax('url'));
+ $this->assertStringContainsString('custom_script', $builder->getAjax('data'));
+ $this->assertStringContainsString('data.id = 123', $builder->getAjax('data'));
+ $this->assertStringContainsString("data.name = 'yajra'", $builder->getAjax('data'));
+
+ $builder->postAjaxWithForm('/test', '#formId');
+ $this->assertStringContainsString('find("input, select, textarea").serializeArray()', $builder->getAjax()['data']);
+ $this->assertStringContainsString('#formId', $builder->getAjax('data'));
+ }
+
+ #[Test]
+ public function it_has_features_options()
+ {
+ $builder = $this->getHtmlBuilder();
+ $builder->autoWidth()
+ ->deferRender()
+ ->info()
+ ->lengthChange()
+ ->ordering()
+ ->processing()
+ ->scrollX()
+ ->scrollY()
+ ->paging()
+ ->searching()
+ ->serverSide()
+ ->stateSave();
+
+ $this->assertEquals(true, $builder->getAttribute('autoWidth'));
+ $this->assertEquals(true, $builder->getAttribute('deferRender'));
+ $this->assertEquals(true, $builder->getAttribute('info'));
+ $this->assertEquals(true, $builder->getAttribute('lengthChange'));
+ $this->assertEquals(true, $builder->getAttribute('ordering'));
+ $this->assertEquals(true, $builder->getAttribute('processing'));
+ $this->assertEquals(true, $builder->getAttribute('scrollX'));
+ $this->assertEquals(true, $builder->getAttribute('scrollY'));
+ $this->assertEquals(true, $builder->getAttribute('paging'));
+ $this->assertEquals(true, $builder->getAttribute('searching'));
+ $this->assertEquals(true, $builder->getAttribute('serverSide'));
+ $this->assertEquals(true, $builder->getAttribute('stateSave'));
+
+ $builder->scrollY('50vh');
+ $this->assertEquals('50vh', $builder->getAttribute('scrollY'));
+ }
+
+ #[Test]
+ public function it_has_internationalisation_options()
+ {
+ $builder = $this->getHtmlBuilder();
+
+ $builder->language('/language-url')
+ ->languageDecimal(',')
+ ->languageEmptyTable('languageEmptyTable')
+ ->languageInfo('languageInfo')
+ ->languageInfoEmpty('languageInfoEmpty')
+ ->languageInfoFiltered('languageInfoFiltered')
+ ->languageInfoPostFix('languageInfoPostFix')
+ ->languageLengthMenu('languageLengthMenu')
+ ->languageLoadingRecords('languageLoadingRecords')
+ ->languageProcessing('languageProcessing')
+ ->languageSearch('languageSearch')
+ ->languageSearchPlaceholder('languageSearchPlaceholder')
+ ->languageThousands('languageThousands')
+ ->languageZeroRecords('languageZeroRecords');
+
+ $this->assertEquals('/language-url', $builder->getAttribute('language')['url']);
+ $this->assertEquals(',', $builder->getLanguage('decimal'));
+ $this->assertEquals('languageEmptyTable', $builder->getLanguage('emptyTable'));
+ $this->assertEquals('languageInfo', $builder->getLanguage('info'));
+ $this->assertEquals('languageInfoEmpty', $builder->getLanguage('infoEmpty'));
+ $this->assertEquals('languageInfoFiltered', $builder->getLanguage('infoFiltered'));
+ $this->assertEquals('languageInfoPostFix', $builder->getLanguage('infoPostFix'));
+ $this->assertEquals('languageLengthMenu', $builder->getLanguage('lengthMenu'));
+ $this->assertEquals('languageLoadingRecords', $builder->getLanguage('loadingRecords'));
+ $this->assertEquals('languageProcessing', $builder->getLanguage('processing'));
+ $this->assertEquals('languageSearch', $builder->getLanguage('search'));
+ $this->assertEquals('languageSearchPlaceholder', $builder->getLanguage('searchPlaceholder'));
+ $this->assertEquals('languageThousands', $builder->getLanguage('thousands'));
+ $this->assertEquals('languageZeroRecords', $builder->getLanguage('zeroRecords'));
+
+ $builder->languageUrl('languageUrl');
+ $this->assertEquals('languageUrl', $builder->getLanguage('url'));
+ }
+
+ #[Test]
+ public function it_has_plugin_attribute_getter()
+ {
+ $builder = $this->getHtmlBuilder();
+
+ $builder->selectStyleSingle();
+
+ $this->assertEquals(Builder::SELECT_STYLE_SINGLE, $builder->getPluginAttribute('select', 'style'));
+ }
+
+ #[Test]
+ public function it_has_options()
+ {
+ $builder = $this->getHtmlBuilder();
+ $builder->deferLoading(10)
+ ->destroy(true)
+ ->displayStart(1)
+ ->dom('Bf')
+ ->lengthMenu()
+ ->orders([[1, 'asc']])
+ ->orderCellsTop()
+ ->orderClasses()
+ ->orderBy(2)
+ ->orderBy(3, 'asc')
+ ->orderByFixed(3, 'asc')
+ ->orderMulti()
+ ->pageLength()
+ ->pagingType()
+ ->renderer()
+ ->retrieve()
+ ->rowId()
+ ->scrollCollapse()
+ ->search([])
+ ->searchCols([])
+ ->searchDelay(10)
+ ->stateDuration(10)
+ ->stripeClasses(['stripeClasses'])
+ ->tabIndex(2);
+
+ $this->assertEquals(10, $builder->getAttribute('deferLoading'));
+ $this->assertEquals(true, $builder->getAttribute('destroy'));
+ $this->assertEquals(1, $builder->getAttribute('displayStart'));
+ $this->assertEquals('Bf', $builder->getAttribute('dom'));
+ $this->assertEquals([10, 25, 50, 100], $builder->getAttribute('lengthMenu'));
+ $this->assertEquals([1, 'asc'], $builder->getAttribute('order')[0]);
+ $this->assertEquals([2, 'desc'], $builder->getAttribute('order')[1]);
+ $this->assertEquals([3, 'asc'], $builder->getAttribute('order')[2]);
+ $this->assertEquals(false, $builder->getAttribute('orderCellsTop'));
+ $this->assertEquals(true, $builder->getAttribute('orderClasses'));
+ $this->assertEquals([[3, 'asc']], $builder->getAttribute('orderFixed'));
+ $this->assertEquals(true, $builder->getAttribute('orderMulti'));
+ $this->assertEquals(10, $builder->getAttribute('pageLength'));
+ $this->assertEquals('simple_numbers', $builder->getAttribute('pagingType'));
+ $this->assertEquals('bootstrap', $builder->getAttribute('renderer'));
+ $this->assertEquals(false, $builder->getAttribute('scrollCollapse'));
+ $this->assertEquals([], $builder->getAttribute('search'));
+ $this->assertEquals([], $builder->getAttribute('searchCols'));
+ $this->assertEquals(10, $builder->getAttribute('searchDelay'));
+ $this->assertEquals(10, $builder->getAttribute('stateDuration'));
+ $this->assertEquals(['stripeClasses'], $builder->getAttribute('stripeClasses'));
+ $this->assertEquals(2, $builder->getAttribute('tabIndex'));
+ }
+}
diff --git a/tests/Html/Builder/BuilderTest.php b/tests/Html/Builder/BuilderTest.php
new file mode 100644
index 0000000..1b61ef2
--- /dev/null
+++ b/tests/Html/Builder/BuilderTest.php
@@ -0,0 +1,306 @@
+getHtmlBuilder()->scripts()->toHtml();
+
+ $this->assertStringContainsString('type="text/javascript"', $html);
+ }
+
+ #[Test]
+ public function it_can_set_script_type_attribute()
+ {
+ $html = $this->getHtmlBuilder()->scripts(attributes: ['type' => 'module'])->toHtml();
+
+ $this->assertStringContainsString('type="module"', $html);
+ }
+
+ #[Test]
+ public function it_can_set_multiple_script_attributes()
+ {
+ $html = $this->getHtmlBuilder()->scripts(attributes: ['prop1' => 'val1', 'prop2' => 'val2'])->toHtml();
+
+ $this->assertStringContainsString('prop1="val1"', $html);
+ $this->assertStringContainsString('prop2="val2"', $html);
+ }
+
+ #[Test]
+ public function it_can_use_vitejs_module_script()
+ {
+ Builder::useVite();
+
+ $this->assertStringContainsString('type="module"', $this->getHtmlBuilder()->scripts()->toHtml());
+
+ Builder::useWebpack();
+ }
+
+ #[Test]
+ public function it_can_resolved_builder_class()
+ {
+ $builder = $this->getHtmlBuilder();
+
+ $this->assertInstanceOf(Builder::class, $builder);
+
+ $builder = app('datatables.html');
+ $this->assertInstanceOf(Builder::class, $builder);
+ }
+
+ #[Test]
+ public function it_can_read_table_id_from_config()
+ {
+ $this->assertEquals('dataTableBuilder', $this->getHtmlBuilder()->getTableId());
+
+ config()->set('datatables-html.table.id', 'test');
+
+ $this->assertEquals('test', $this->getHtmlBuilder()->getTableId());
+ }
+
+ #[Test]
+ public function it_can_change_namespace()
+ {
+ $builder = $this->getHtmlBuilder();
+
+ $this->assertStringContainsString('LaravelDataTables', $builder->scripts()->toHtml());
+
+ config()->set('datatables-html.namespace', 'TestDataTables');
+
+ $this->assertStringContainsString('TestDataTables', $builder->scripts()->toHtml());
+ }
+
+ #[Test]
+ public function it_can_generate_table_html_and_scripts()
+ {
+ $builder = $this->getHtmlBuilder();
+
+ $builder->setTableId('foo-table')
+ ->columns([
+ Column::make('foo'),
+ Column::make('baz'),
+ ]);
+
+ $table = $builder->table()->toHtml();
+
+ $expected = '';
+ $this->assertEquals($expected, $table);
+
+ $script = $builder->scripts()->toHtml();
+ $expected = '';
+ $this->assertEquals($expected, $script);
+
+ $expected = 'document.addEventListener("DOMContentLoaded",function(){window.LaravelDataTables=window.LaravelDataTables||{};window.LaravelDataTables["foo-table"]=$("#foo-table").DataTable({"serverSide":true,"processing":true,"ajax":"","columns":[{"data":"foo","name":"foo","title":"Foo","orderable":true,"searchable":true},{"data":"baz","name":"baz","title":"Baz","orderable":true,"searchable":true}]});});';
+ $this->assertEquals($expected, $builder->generateScripts()->toHtml());
+ }
+
+ #[Test]
+ public function it_can_set_table_attribute()
+ {
+ $builder = $this->getHtmlBuilder();
+
+ $builder->setTableAttribute('attr', 'val');
+
+ $this->assertEquals('val', $builder->getTableAttribute('attr'));
+ }
+
+ #[Test]
+ public function it_can_set_table_id_attribute()
+ {
+ $builder = $this->getHtmlBuilder();
+
+ $builder->setTableId('val');
+
+ $this->assertEquals('val', $builder->getTableAttribute('id'));
+ }
+
+ #[Test]
+ public function it_can_set_multiple_table_attributes()
+ {
+ $builder = $this->getHtmlBuilder();
+
+ $builder->setTableAttribute(['prop1' => 'val1', 'prop2' => 'val2']);
+
+ $this->assertEquals('val1', $builder->getTableAttribute('prop1'));
+ $this->assertEquals('val2', $builder->getTableAttribute('prop2'));
+ }
+
+ #[Test]
+ public function it_can_get_inexistent_table_attribute_throws()
+ {
+ $builder = $this->getHtmlBuilder();
+
+ $attr = $builder->getTableAttribute('boohoo');
+
+ $this->assertEmpty($attr);
+ }
+
+ #[Test]
+ public function it_can_add_table_class_attribute()
+ {
+ $builder = $this->getHtmlBuilder();
+ $this->assertEquals('table', $builder->getTableAttribute('class'));
+
+ $builder->addTableClass('foo');
+ $this->assertEquals('table foo', $builder->getTableAttribute('class'));
+
+ $builder->addTableClass(' foo bar ');
+ $this->assertEquals('table foo bar', $builder->getTableAttribute('class'));
+
+ $builder->addTableClass([' a-b ', 'foo c bar', 'key' => 'value']);
+ $this->assertEquals('table foo bar a-b c value', $builder->getTableAttribute('class'));
+ }
+
+ #[Test]
+ public function it_can_remove_table_class_attribute()
+ {
+ $builder = $this->getHtmlBuilder();
+ $builder->setTableAttribute('class', ' foo bar a b c ');
+
+ $builder->removeTableClass('bar');
+ $this->assertEquals('foo a b c', $builder->getTableAttribute('class'));
+
+ $builder->removeTableClass(' x c y ');
+ $this->assertEquals('foo a b', $builder->getTableAttribute('class'));
+
+ $builder->removeTableClass(['a' => ' b ', ' foo bar ']);
+ $this->assertEquals('a', $builder->getTableAttribute('class'));
+ }
+
+ #[Test]
+ public function it_can_add_checkbox()
+ {
+ $builder = $this->getHtmlBuilder();
+ $builder->addCheckbox();
+
+ $column = $builder->getColumns()[0];
+
+ $this->assertCount(1, $builder->getColumns());
+ $this->assertInstanceOf(Column::class, $column);
+ $this->assertEquals(false, $column->orderable);
+ $this->assertEquals(false, $column->searchable);
+ $this->assertEquals(false, $column->exportable);
+ $this->assertEquals(true, $column->printable);
+ }
+
+ #[Test]
+ public function it_can_add_index_column()
+ {
+ $builder = $this->getHtmlBuilder();
+ $builder->addIndex();
+
+ $column = $builder->getColumns()[0];
+
+ $this->assertCount(1, $builder->getColumns());
+ $this->assertInstanceOf(Column::class, $column);
+ $this->assertEquals(false, $column->orderable);
+ $this->assertEquals(false, $column->searchable);
+ $this->assertEquals(false, $column->exportable);
+ $this->assertEquals(true, $column->printable);
+ }
+
+ #[Test]
+ public function it_can_add_action_column()
+ {
+ $builder = $this->getHtmlBuilder();
+ $builder->addAction();
+
+ $column = $builder->getColumns()[0];
+
+ $this->assertCount(1, $builder->getColumns());
+ $this->assertInstanceOf(Column::class, $column);
+ $this->assertEquals(false, $column->orderable);
+ $this->assertEquals(false, $column->searchable);
+ $this->assertEquals(false, $column->exportable);
+ $this->assertEquals(true, $column->printable);
+ }
+
+ #[Test]
+ public function it_has_column_defs()
+ {
+ $builder = $this->getHtmlBuilder();
+ $builder->columnDefs([['targets' => '_all']]);
+
+ $this->assertEquals([['targets' => '_all']], $builder->getAttribute('columnDefs'));
+ $this->assertCount(1, $builder->getAttribute('columnDefs'));
+
+ $builder->columnDefs([ColumnDefinition::make()->targets('_all')->visible()]);
+
+ $this->assertEquals([['targets' => '_all', 'visible' => true]], $builder->getAttribute('columnDefs'));
+ $this->assertCount(1, $builder->getAttribute('columnDefs'));
+
+ $builder->addColumnDef(ColumnDefinition::make()->targets([1]));
+ $this->assertEquals(['targets' => [1]], $builder->getAttribute('columnDefs')[1]);
+ $this->assertCount(2, $builder->getAttribute('columnDefs'));
+
+ $builder->columnDefs(ColumnDefinitions::make()->push(ColumnDefinition::make()->targets(1)));
+ $this->assertEquals([['targets' => 1]], $builder->getAttribute('columnDefs'));
+ $this->assertCount(1, $builder->getAttribute('columnDefs'));
+ }
+
+ #[Test]
+ public function it_has_table_options()
+ {
+ $builder = $this->getHtmlBuilder();
+ $builder->setTableId('my-table');
+
+ $this->assertEquals('my-table', $builder->getTableId());
+ $this->assertEquals(['id' => 'my-table', 'class' => 'table'], $builder->getTableAttributes());
+
+ $builder->setTableAttribute('class', 'dTable');
+ $this->assertEquals(['id' => 'my-table', 'class' => 'dTable'], $builder->getTableAttributes());
+
+ $builder->addTableClass('table');
+ $this->assertEquals(['id' => 'my-table', 'class' => 'dTable table'], $builder->getTableAttributes());
+
+ $builder->removeTableClass('dTable');
+ $this->assertEquals(['id' => 'my-table', 'class' => 'table'], $builder->getTableAttributes());
+
+ $this->assertInstanceOf(HtmlString::class, $builder->table());
+ $this->assertEquals('', $builder->table()->toHtml());
+
+ $builder->setTableHeadClass('thead-dark');
+ $this->assertEquals('', $builder->table()->toHtml());
+ }
+
+ #[Test]
+ public function it_has_editors()
+ {
+ $builder = $this->getHtmlBuilder();
+
+ $builder->editor(Editor::make());
+ $this->assertCount(1, $builder->getEditors());
+
+ $builder->editors([
+ Editor::make(),
+ Editor::make('edit'),
+ ]);
+ $this->assertCount(2, $builder->getEditors());
+ }
+
+ #[Test]
+ public function it_ignores_unauthorized_columns(): void
+ {
+ $builder = $this->getHtmlBuilder();
+
+ $builder->columns([
+ Column::makeIf(false)
+ ->title('unauthorized_column'),
+
+ Column::make('authorized_column'),
+ ]);
+
+ $this->assertCount(1, $builder->getColumns());
+ }
+}
diff --git a/tests/Html/Builder/LayoutTest.php b/tests/Html/Builder/LayoutTest.php
new file mode 100644
index 0000000..3f46723
--- /dev/null
+++ b/tests/Html/Builder/LayoutTest.php
@@ -0,0 +1,319 @@
+top('test');
+ $this->assertEquals('test', $layout->get('top'));
+
+ $layout->bottom('test');
+ $this->assertEquals('test', $layout->get('bottom'));
+
+ $layout->topStart('test');
+ $this->assertEquals('test', $layout->get('topStart'));
+
+ $layout->topEnd('test');
+ $this->assertEquals('test', $layout->get('topEnd'));
+
+ $layout->bottomStart('test');
+ $this->assertEquals('test', $layout->get('bottomStart'));
+
+ $layout->bottomEnd('test');
+ $this->assertEquals('test', $layout->get('bottomEnd'));
+
+ $layout->top('test', 1);
+ $this->assertEquals('test', $layout->get('top1'));
+
+ $layout->bottom('test', 1);
+ $this->assertEquals('test', $layout->get('bottom1'));
+
+ $layout->topStart('test', 1);
+ $this->assertEquals('test', $layout->get('top1Start'));
+
+ $layout->bottomStart('test', 1);
+ $this->assertEquals('test', $layout->get('bottom1Start'));
+
+ $layout->topEnd('test', 1);
+ $this->assertEquals('test', $layout->get('top1End'));
+
+ $layout->bottomEnd('test', 1);
+ $this->assertEquals('test', $layout->get('bottom1End'));
+ }
+
+ #[Test]
+ public function it_can_be_used_in_builder(): void
+ {
+ $builder = resolve(Builder::class);
+ $builder->layout(function (Layout $layout) {
+ $layout->top('test');
+ $layout->bottom('test');
+ $layout->topStart('test');
+ $layout->topEnd('test');
+ $layout->bottomStart('test');
+ $layout->bottomEnd('test');
+ $layout->top('test', 1);
+ $layout->bottom('test', 1);
+ $layout->topStart('test', 1);
+ $layout->bottomStart('test', 1);
+ $layout->topEnd('test', 1);
+ $layout->bottomEnd('test', 1);
+ });
+
+ $this->assertArrayHasKey('layout', $builder->getAttributes());
+ $this->assertArrayHasKey('top', $builder->getAttributes()['layout']);
+ $this->assertArrayHasKey('bottom', $builder->getAttributes()['layout']);
+ $this->assertArrayHasKey('topStart', $builder->getAttributes()['layout']);
+ $this->assertArrayHasKey('topEnd', $builder->getAttributes()['layout']);
+ $this->assertArrayHasKey('bottomStart', $builder->getAttributes()['layout']);
+ $this->assertArrayHasKey('bottomEnd', $builder->getAttributes()['layout']);
+ $this->assertArrayHasKey('top1', $builder->getAttributes()['layout']);
+ $this->assertArrayHasKey('bottom1', $builder->getAttributes()['layout']);
+ $this->assertArrayHasKey('top1Start', $builder->getAttributes()['layout']);
+ $this->assertArrayHasKey('bottom1Start', $builder->getAttributes()['layout']);
+ $this->assertArrayHasKey('top1End', $builder->getAttributes()['layout']);
+ $this->assertArrayHasKey('bottom1End', $builder->getAttributes()['layout']);
+ }
+
+ #[Test]
+ public function it_has_factory_method(): void
+ {
+ $layout = Layout::make();
+ $this->assertInstanceOf(Layout::class, $layout);
+
+ $builder = resolve(Builder::class);
+ $builder->layout(Layout::make());
+
+ $this->assertArrayHasKey('layout', $builder->getAttributes());
+ }
+
+ #[Test]
+ public function it_can_be_macroable(): void
+ {
+ Layout::macro('test', fn () => 'test');
+
+ $layout = new Layout;
+ $this->assertEquals('test', $layout->test());
+ }
+
+ #[Test]
+ public function it_can_accept_array(): void
+ {
+ $layout = new Layout(['top' => 'test']);
+ $this->assertEquals('test', $layout->get('top'));
+ }
+
+ #[Test]
+ public function it_can_accept_array_as_parameter(): void
+ {
+ $layout = Layout::make(['top' => 'test']);
+ $this->assertEquals('test', $layout->get('top'));
+ }
+
+ #[Test]
+ public function it_can_accept_array_as_parameter_in_builder(): void
+ {
+ $builder = resolve(Builder::class);
+ $builder->layout(['top' => 'test']);
+
+ $this->assertArrayHasKey('layout', $builder->getAttributes());
+ $this->assertArrayHasKey('top', $builder->getAttributes()['layout']);
+ }
+
+ #[Test]
+ public function it_can_accept_callable_as_parameter_in_builder(): void
+ {
+ $builder = resolve(Builder::class);
+ $builder->layout(fn (Layout $layout) => $layout->top('test'));
+
+ $this->assertArrayHasKey('layout', $builder->getAttributes());
+ $this->assertArrayHasKey('top', $builder->getAttributes()['layout']);
+ }
+
+ #[Test]
+ public function it_can_accept_js_selector_for_layout_content(): void
+ {
+ $builder = resolve(Builder::class);
+ $builder->layout(fn (Layout $layout) => $layout->topView('#test'));
+
+ $this->assertArrayHasKey('layout', $builder->getAttributes());
+ $this->assertArrayHasKey('top', $builder->getAttributes()['layout']);
+ $this->assertEquals("function() { return $('#test').html(); }", $builder->getAttributes()['layout']['top']);
+
+ $builder->layout(fn (Layout $layout) => $layout->bottomView('#test'));
+ $this->assertArrayHasKey('layout', $builder->getAttributes());
+ $this->assertArrayHasKey('bottom', $builder->getAttributes()['layout']);
+ $this->assertEquals("function() { return $('#test').html(); }", $builder->getAttributes()['layout']['bottom']);
+
+ $builder->layout(fn (Layout $layout) => $layout->topStartView('#test'));
+ $this->assertArrayHasKey('layout', $builder->getAttributes());
+ $this->assertArrayHasKey('topStart', $builder->getAttributes()['layout']);
+ $this->assertEquals("function() { return $('#test').html(); }",
+ $builder->getAttributes()['layout']['topStart']);
+
+ $builder->layout(fn (Layout $layout) => $layout->topEndView('#test'));
+ $this->assertArrayHasKey('layout', $builder->getAttributes());
+ $this->assertArrayHasKey('topEnd', $builder->getAttributes()['layout']);
+ $this->assertEquals("function() { return $('#test').html(); }", $builder->getAttributes()['layout']['topEnd']);
+
+ $builder->layout(fn (Layout $layout) => $layout->bottomStartView('#test'));
+ $this->assertArrayHasKey('layout', $builder->getAttributes());
+ $this->assertArrayHasKey('bottomStart', $builder->getAttributes()['layout']);
+ $this->assertEquals("function() { return $('#test').html(); }",
+ $builder->getAttributes()['layout']['bottomStart']);
+
+ $builder->layout(fn (Layout $layout) => $layout->bottomEndView('#test'));
+ $this->assertArrayHasKey('layout', $builder->getAttributes());
+ $this->assertArrayHasKey('bottomEnd', $builder->getAttributes()['layout']);
+ $this->assertEquals(
+ "function() { return $('#test').html(); }",
+ $builder->getAttributes()['layout']['bottomEnd']
+ );
+ }
+
+ #[Test]
+ public function it_can_accept_view_instance_or_string_for_layout_content(): void
+ {
+ $builder = resolve(Builder::class);
+
+ $view = view('test-view');
+
+ $builder->layout(fn (Layout $layout) => $layout
+ ->addView(
+ view: new TestView,
+ layoutPosition: LayoutPosition::Top,
+ )
+ ->addView(
+ view: new TestInlineView,
+ layoutPosition: LayoutPosition::Bottom,
+ )
+ ->addView(
+ view: $view,
+ layoutPosition: LayoutPosition::TopStart,
+ order: 1
+ )
+ ->addView(
+ view: 'test-view',
+ layoutPosition: LayoutPosition::BottomEnd,
+ order: 2
+ )
+ ->addView(
+ view: (new TestView)->render(),
+ layoutPosition: LayoutPosition::Top,
+ order: 3
+ )
+ ->addView(
+ view: (new TestInlineView)->render(),
+ layoutPosition: LayoutPosition::Bottom,
+ order: 4
+ )
+ );
+
+ $this->assertArrayHasKey('layout', $builder->getAttributes());
+ $this->assertCount(6, $builder->getAttributes()['layout']);
+
+ $this->assertArrayHasKey('top', $builder->getAttributes()['layout']);
+ $this->assertEquals(
+ 'function() { return '.json_encode($view->render()).'; }',
+ $builder->getAttributes()['layout']['top']
+ );
+
+ $this->assertArrayHasKey('bottom', $builder->getAttributes()['layout']);
+ $this->assertEquals(
+ 'function() { return '.json_encode('Test Inline View
').'; }',
+ $builder->getAttributes()['layout']['bottom']
+ );
+
+ $this->assertArrayHasKey('top1Start', $builder->getAttributes()['layout']);
+ $this->assertEquals(
+ 'function() { return '.json_encode($view->render()).'; }',
+ $builder->getAttributes()['layout']['top1Start']
+ );
+
+ $this->assertArrayHasKey('bottom2End', $builder->getAttributes()['layout']);
+ $this->assertEquals(
+ 'function() { return '.json_encode($view->render()).'; }',
+ $builder->getAttributes()['layout']['bottom2End']
+ );
+
+ $this->assertArrayHasKey('top3', $builder->getAttributes()['layout']);
+ $this->assertEquals(
+ 'function() { return '.json_encode($view->render()).'; }',
+ $builder->getAttributes()['layout']['top3']
+ );
+
+ $this->assertArrayHasKey('bottom4', $builder->getAttributes()['layout']);
+ $this->assertEquals(
+ 'function() { return '.json_encode('Test Inline View
').'; }',
+ $builder->getAttributes()['layout']['bottom4']
+ );
+ }
+
+ #[Test]
+ public function it_throws_an_exception_if_the_view_does_not_exist_when_adding_view(): void
+ {
+ $this->expectException(InvalidArgumentException::class);
+ $this->expectExceptionMessage('View [non-existent-view] not found.');
+
+ $builder = resolve(Builder::class);
+ $builder->layout(fn (Layout $layout) => $layout
+ ->addView(
+ view: 'non-existent-view',
+ layoutPosition: LayoutPosition::Top,
+ )
+ ->addView(
+ view: view('non-existent-view'),
+ layoutPosition: LayoutPosition::Bottom,
+ ));
+ }
+
+ #[Test]
+ public function it_can_accept_livewire_component_as_layout_content(): void
+ {
+ $builder = resolve(Builder::class);
+ $builder->layout(fn (Layout $layout) => $layout
+ ->addLivewire(TestLivewire::class, LayoutPosition::TopStart, 1)
+ ->addLivewire(TestLivewire::class, LayoutPosition::BottomEnd, 2));
+
+ $this->assertArrayHasKey('layout', $builder->getAttributes());
+ $this->assertArrayHasKey('top1Start', $builder->getAttributes()['layout']);
+ $this->assertStringContainsString(
+ 'test livewire',
+ $builder->getAttributes()['layout']['top1Start']
+ );
+
+ $this->assertArrayHasKey('layout', $builder->getAttributes());
+ $this->assertArrayHasKey('bottom2End', $builder->getAttributes()['layout']);
+ $this->assertStringContainsString(
+ 'test livewire',
+ $builder->getAttributes()['layout']['bottom2End']
+ );
+ }
+
+ #[Test]
+ public function it_throws_an_exception_if_the_livewire_component_does_not_exist_when_adding_livewire_component(): void
+ {
+ $this->expectException(ComponentNotFoundException::class);
+ $this->expectExceptionMessage('Unable to find component: [Yajra\DataTables\Html\Tests\TestComponents\TestView]');
+
+ $builder = resolve(Builder::class);
+ $builder->layout(fn (Layout $layout) => $layout
+ ->addLivewire(TestView::class, LayoutPosition::Top)
+ ->addLivewire(TestView::class, LayoutPosition::Bottom));
+ }
+}
diff --git a/tests/Html/Column/ColumnDefinitionTest.php b/tests/Html/Column/ColumnDefinitionTest.php
new file mode 100644
index 0000000..47bff1d
--- /dev/null
+++ b/tests/Html/Column/ColumnDefinitionTest.php
@@ -0,0 +1,29 @@
+targets([1])
+ ->columns([])
+ ->cellType()
+ ->className('my-class')
+ ->contentPadding('mmm')
+ ->createdCell('fn');
+
+ $this->assertEquals([1], $def->targets);
+ $this->assertEquals([], $def->columns);
+ $this->assertEquals('th', $def->cellType);
+ $this->assertEquals('my-class', $def->className);
+ $this->assertEquals('mmm', $def->contentPadding);
+ $this->assertEquals('fn', $def->createdCell);
+ }
+}
diff --git a/tests/Html/Column/ColumnTest.php b/tests/Html/Column/ColumnTest.php
new file mode 100644
index 0000000..c5da073
--- /dev/null
+++ b/tests/Html/Column/ColumnTest.php
@@ -0,0 +1,226 @@
+assertInstanceOf(Column::class, $column);
+ }
+
+ #[Test]
+ public function it_has_default_properties()
+ {
+ $column = Column::make('name');
+
+ $this->assertEquals('name', $column->name);
+ $this->assertEquals('name', $column->data);
+ $this->assertEquals('Name', $column->title);
+ $this->assertEquals('', $column->render);
+ $this->assertEquals(true, $column->exportable);
+ $this->assertEquals(true, $column->printable);
+ $this->assertEquals(true, $column->orderable);
+ $this->assertEquals(true, $column->searchable);
+ $this->assertEquals([], $column->attributes);
+ $this->assertEquals('', $column->footer);
+ }
+
+ #[Test]
+ public function it_can_format_title()
+ {
+ $this->assertEquals('Title', Column::titleFormat('title'));
+ }
+
+ #[Test]
+ public function it_can_make_computed_column()
+ {
+ $column = Column::computed('name');
+
+ $this->assertEquals('name', $column->name);
+ $this->assertEquals('name', $column->data);
+ $this->assertEquals('Name', $column->title);
+ $this->assertEquals('', $column->render);
+ $this->assertEquals(true, $column->exportable);
+ $this->assertEquals(true, $column->printable);
+ $this->assertEquals(false, $column->orderable);
+ $this->assertEquals(false, $column->searchable);
+ $this->assertEquals([], $column->attributes);
+ $this->assertEquals('', $column->footer);
+ }
+
+ #[Test]
+ public function it_can_make_formatted_column()
+ {
+ $column = Column::formatted('name');
+
+ $this->assertEquals('name', $column->name);
+ $this->assertEquals('name', $column->data);
+ $this->assertEquals('Name', $column->title);
+ $this->assertEquals('function(data,type,full,meta){return full.name_formatted;}', $column->render);
+ $this->assertEquals(true, $column->exportable);
+ $this->assertEquals(true, $column->printable);
+ $this->assertEquals(true, $column->orderable);
+ $this->assertEquals(true, $column->searchable);
+ $this->assertEquals([], $column->attributes);
+ $this->assertEquals('', $column->footer);
+ }
+
+ #[Test]
+ public function it_can_make_a_checkbox()
+ {
+ $column = Column::checkbox('name');
+
+ $this->assertEquals('', $column->name);
+ $this->assertEquals('', $column->data);
+ $this->assertEquals('name', $column->title);
+ $this->assertEquals('', $column->render);
+ $this->assertEquals(true, $column->printable);
+ $this->assertEquals(false, $column->exportable);
+ $this->assertEquals(false, $column->orderable);
+ $this->assertEquals(false, $column->searchable);
+ $this->assertEquals('select-checkbox', $column->className);
+ $this->assertEquals([], $column->attributes);
+ $this->assertEquals('', $column->footer);
+ }
+
+ #[Test]
+ public function it_has_property_setters()
+ {
+ $column = Column::checkbox('name');
+
+ $column->name('test');
+ $this->assertEquals('test', $column->name);
+
+ $column->data('test');
+ $this->assertEquals('test', $column->data);
+
+ $column->title('test');
+ $this->assertEquals('test', $column->title);
+
+ $column->editField('test');
+ $this->assertEquals('test', $column->editField);
+
+ $column->orderData(1);
+ $this->assertEquals(1, $column->orderData);
+
+ $column->orderData([1]);
+ $this->assertEquals([1], $column->orderData);
+
+ $column->orderDataType('test');
+ $this->assertEquals('test', $column->orderDataType);
+
+ $column->orderSequence(['test']);
+ $this->assertEquals(['test'], $column->orderSequence);
+
+ $column->cellType('test');
+ $this->assertEquals('test', $column->cellType);
+
+ $column->type('test');
+ $this->assertEquals('test', $column->type);
+
+ $column->contentPadding('test');
+ $this->assertEquals('test', $column->contentPadding);
+
+ $column->createdCell('test');
+ $this->assertEquals('test', $column->createdCell);
+
+ $column->titleAttr('test');
+ $this->assertEquals('test', $column->titleAttr);
+
+ $column->exportFormat('test');
+ $this->assertEquals('test', $column->exportFormat);
+ }
+
+ #[Test]
+ public function it_can_render_scripts()
+ {
+ $column = Column::make('name');
+
+ $column->render('test');
+ $this->assertEquals('function(data,type,full,meta){return test;}', $column->render);
+
+ $column->render('$.fn.dataTable.render.test');
+ $this->assertEquals('$.fn.dataTable.render.test', $column->render);
+
+ $column->renderJs('test');
+ $this->assertEquals('$.fn.dataTable.render.test', $column->render);
+
+ $column->renderRaw('test');
+ $this->assertEquals('test', $column->render);
+ }
+
+ #[Test]
+ public function it_allows_orthogonal_data()
+ {
+ $expected = [
+ '_' => 'test',
+ 'sort' => 'test',
+ 'filter' => 'test',
+ 'type' => 'test',
+ ];
+ $column = Column::make('name')->data($expected);
+
+ $this->assertEquals($expected, $column->data);
+ }
+
+ #[Test]
+ public function it_has_responsive_priority()
+ {
+ $column = Column::make('name');
+ $column->responsivePriority(1);
+
+ $this->assertEquals(1, $column->responsivePriority);
+ }
+
+ #[Test]
+ public function it_can_add_class()
+ {
+ $column = Column::make('name')->className('text-sm');
+ $this->assertEquals('text-sm', $column->className);
+
+ $column->addClass('font-bold');
+ $this->assertEquals('text-sm font-bold', $column->className);
+ }
+
+ #[Test]
+ public function it_has_authorizations()
+ {
+ $column = Column::makeIf(true, 'name');
+ $this->assertEquals([
+ 'name' => 'name',
+ 'data' => 'name',
+ 'title' => 'Name',
+ 'orderable' => true,
+ 'searchable' => true,
+ 'attributes' => [],
+ ], $column->toArray());
+
+ $column = Column::makeIf(false, 'name');
+ $this->assertEquals([], $column->toArray());
+ }
+
+ #[Test]
+ public function it_can_be_serialized()
+ {
+ $column = Column::make('name');
+ $this->assertEquals([
+ 'name' => 'name',
+ 'data' => 'name',
+ 'title' => 'Name',
+ 'orderable' => true,
+ 'searchable' => true,
+ 'attributes' => [],
+ ], $column->toArray());
+
+ $expected = '{"data":"name","name":"name","title":"Name","orderable":true,"searchable":true,"attributes":[]}';
+ $this->assertEquals($expected, $column->toJson());
+ }
+}
diff --git a/tests/Html/Editor/EditorFormOptionsTest.php b/tests/Html/Editor/EditorFormOptionsTest.php
new file mode 100644
index 0000000..ae45186
--- /dev/null
+++ b/tests/Html/Editor/EditorFormOptionsTest.php
@@ -0,0 +1,52 @@
+assertInstanceOf(FormOptions::class, $options);
+
+ $options->focus(1)
+ ->message('message')
+ ->onBackground('onBackground')
+ ->onBlur('onBlur')
+ ->onComplete('onComplete')
+ ->onEsc('onEsc')
+ ->onFieldError('onFieldError')
+ ->onReturn('onReturn')
+ ->submit('submit')
+ ->title('title')
+ ->drawType('drawType')
+ ->formScope('scope')
+ ->nest(false)
+ ->buttons([])
+ ->submitTrigger(1)
+ ->submitHtml('submitHtml');
+
+ $this->assertEquals(1, $options->focus);
+ $this->assertEquals('message', $options->message);
+ $this->assertEquals('onBackground', $options->onBackground);
+ $this->assertEquals('onBlur', $options->onBlur);
+ $this->assertEquals('onComplete', $options->onComplete);
+ $this->assertEquals('onEsc', $options->onEsc);
+ $this->assertEquals('onFieldError', $options->onFieldError);
+ $this->assertEquals('onReturn', $options->onReturn);
+ $this->assertEquals('submit', $options->submit);
+ $this->assertEquals('title', $options->title);
+ $this->assertEquals('drawType', $options->drawType);
+ $this->assertEquals('scope', $options->scope);
+ $this->assertEquals(false, $options->nest);
+ $this->assertEquals([], $options->buttons);
+ $this->assertEquals(1, $options->submitTrigger);
+ $this->assertEquals('submitHtml', $options->submitHtml);
+ }
+}
diff --git a/tests/Html/Editor/EditorTest.php b/tests/Html/Editor/EditorTest.php
new file mode 100644
index 0000000..fbb2fd3
--- /dev/null
+++ b/tests/Html/Editor/EditorTest.php
@@ -0,0 +1,197 @@
+getEditor();
+
+ $this->assertInstanceOf(Editor::class, $editor);
+ $this->assertEquals('editor', $editor->instance);
+ $this->assertEmpty($editor->fields);
+ $this->assertEmpty($editor->ajax);
+ $this->assertEmpty($editor->template);
+
+ $editor
+ ->idSrc()
+ ->fields([
+ Text::make('name'),
+ ])
+ ->ajax('/test')
+ ->template('#template');
+
+ $this->assertCount(1, $editor->fields);
+ $this->assertEquals('/test', $editor->ajax);
+ $this->assertEquals('#template', $editor->template);
+ $this->assertEquals('DT_RowId', $editor->idSrc);
+ }
+
+ protected function getEditor(string $instance = 'editor'): Editor
+ {
+ return Editor::make($instance);
+ }
+
+ #[Test]
+ public function it_can_have_events()
+ {
+ $editor = $this->getEditor();
+
+ $editor->onPostSubmit('post');
+ $editor->onDisplayOrder('display');
+
+ $this->assertCount(2, $editor->events);
+
+ $event = [
+ 'event' => 'postSubmit',
+ 'script' => 'post',
+ ];
+
+ $this->assertEquals($event, $editor->events[0]);
+ }
+
+ #[Test]
+ public function it_can_show_hide_fields()
+ {
+ $editor = $this->getEditor();
+
+ $editor->hiddenOnCreate(['name']);
+ $editor->hiddenOnEdit(['email']);
+
+ $this->assertCount(2, $editor->events);
+
+ $this->assertEquals('preOpen', $editor->events[0]['event']);
+ $this->assertStringContainsString("action === 'create'", $editor->events[0]['script']);
+ $this->assertStringContainsString("this.hide('name')", $editor->events[0]['script']);
+
+ $this->assertEquals('preOpen', $editor->events[1]['event']);
+ $this->assertStringContainsString("action === 'edit'", $editor->events[1]['script']);
+ $this->assertStringContainsString("this.hide('email')", $editor->events[1]['script']);
+ }
+
+ #[Test]
+ public function it_has_authorizations()
+ {
+ $editor = Editor::makeIf(true, 'editor')
+ ->fields([
+ Text::make('name'),
+ ]);
+ $this->assertInstanceOf(Editor::class, $editor);
+ $this->assertEquals(true, $editor->isAuthorized());
+ $this->assertEquals([
+ 'instance' => 'editor',
+ 'fields' => [
+ Text::make('name')->toArray(),
+ ],
+ ], $editor->toArray());
+
+ $editor = Editor::makeIf(false, 'editor')
+ ->fields([
+ Text::make('name'),
+ ]);
+ $this->assertInstanceOf(Editor::class, $editor);
+ $this->assertEquals(false, $editor->isAuthorized());
+ $this->assertCount(1, $editor->fields);
+ $this->assertEquals([], $editor->toArray());
+
+ $editor = Editor::makeIfCan('ability', 'editor');
+ $this->assertInstanceOf(Editor::class, $editor);
+ $this->assertEquals(false, $editor->isAuthorized());
+ $this->assertEquals([], $editor->toArray());
+
+ $editor = Editor::makeIfCannot('ability', 'editor');
+ $this->assertInstanceOf(Editor::class, $editor);
+ $this->assertEquals(false, $editor->isAuthorized());
+ $this->assertEquals([], $editor->toArray());
+ }
+
+ #[Test]
+ public function it_can_be_serialized_to_array()
+ {
+ $editor = Editor::make()
+ ->ajax('')
+ ->fields([
+ Text::make('name'),
+ ]);
+
+ $this->assertEquals([
+ 'instance' => 'editor',
+ 'ajax' => '',
+ 'fields' => [
+ Text::make('name')->toArray(),
+ ],
+ ], $editor->toArray());
+ }
+
+ #[Test]
+ public function it_can_be_serialized_to_json_string()
+ {
+ $editor = Editor::make()
+ ->ajax('')
+ ->fields([
+ Text::make('name'),
+ ]);
+
+ $expected = '{"instance":"editor","ajax":"","fields":[{"name":"name","label":"Name","type":"text"}]}';
+ $this->assertEquals($expected, $editor->toJson());
+ }
+
+ #[Test]
+ public function it_has_form_options()
+ {
+ $editor = Editor::make()
+ ->formOptions([
+ 'main' => [
+ 'esc' => true,
+ ],
+ ]);
+
+ $this->assertEquals([
+ 'main' => [
+ 'esc' => true,
+ ],
+ ], $editor->formOptions);
+
+ $editor->formOptionsMain(['esc' => true]);
+ $this->assertEquals(['esc' => true], $editor->formOptions['main']);
+
+ $editor->formOptionsBubble(['esc' => true]);
+ $this->assertEquals(['esc' => true], $editor->formOptions['bubble']);
+
+ $editor->formOptionsInline(['esc' => true]);
+ $this->assertEquals(['esc' => true], $editor->formOptions['inline']);
+ }
+
+ #[Test]
+ public function it_has_display_constants()
+ {
+ $editor = Editor::make()->display(Editor::DISPLAY_BOOTSTRAP);
+ $this->assertEquals('bootstrap', $editor->display);
+
+ $editor->display(Editor::DISPLAY_ENVELOPE);
+ $this->assertEquals('envelope', $editor->display);
+
+ $editor->display(Editor::DISPLAY_FOUNDATION);
+ $this->assertEquals('foundation', $editor->display);
+
+ $editor->display(Editor::DISPLAY_JQUERYUI);
+ $this->assertEquals('jqueryui', $editor->display);
+
+ $editor->display(Editor::DISPLAY_LIGHTBOX);
+ $this->assertEquals('lightbox', $editor->display);
+ }
+
+ #[Test]
+ public function it_has_scripts()
+ {
+ $editor = Editor::make()->scripts('fn');
+ $this->assertEquals('fn', $editor->scripts);
+ }
+}
diff --git a/tests/Html/Editor/Fields/FieldOptionsTest.php b/tests/Html/Editor/Fields/FieldOptionsTest.php
new file mode 100644
index 0000000..413dab6
--- /dev/null
+++ b/tests/Html/Editor/Fields/FieldOptionsTest.php
@@ -0,0 +1,91 @@
+assertEquals([
+ ['label' => __('True'), 'value' => 1],
+ ['label' => __('False'), 'value' => 0],
+ ], $options->toArray());
+ }
+
+ #[Test]
+ public function it_has_yes_no()
+ {
+ $options = Options::yesNo();
+
+ $this->assertEquals([
+ ['label' => __('Yes'), 'value' => 1],
+ ['label' => __('No'), 'value' => 0],
+ ], $options->toArray());
+ }
+
+ #[Test]
+ public function it_can_append_and_prepend()
+ {
+ $options = Options::yesNo();
+
+ $this->assertEquals([
+ ['label' => __('Yes'), 'value' => 1],
+ ['label' => __('No'), 'value' => 0],
+ ], $options->toArray());
+
+ $options->append(__('Maybe'), 2);
+ $this->assertEquals([
+ ['label' => __('Yes'), 'value' => 1],
+ ['label' => __('No'), 'value' => 0],
+ ['label' => __('Maybe'), 'value' => 2],
+ ], $options->toArray());
+
+ $options->prepend(__('IDK'), 3);
+ $this->assertEquals([
+ ['label' => __('IDK'), 'value' => 3],
+ ['label' => __('Yes'), 'value' => 1],
+ ['label' => __('No'), 'value' => 0],
+ ['label' => __('Maybe'), 'value' => 2],
+ ], $options->toArray());
+ }
+
+ #[Test]
+ public function it_can_get_options_from_table()
+ {
+ $options = Options::table('users', 'name');
+ $this->assertCount(20, $options);
+ }
+
+ #[Test]
+ public function it_can_get_options_from_query()
+ {
+ $options = Options::table(DB::table('users')->where('id', 1), 'name');
+ $this->assertCount(1, $options);
+ }
+
+ #[Test]
+ public function it_can_get_options_from_model()
+ {
+ $options = Options::model(User::class, 'name');
+ $this->assertCount(20, $options);
+ }
+
+ #[Test]
+ public function it_can_get_options_from_model_builder()
+ {
+ $options = Options::model(User::query()->whereKey(1), 'name');
+ $this->assertCount(1, $options);
+ }
+}
diff --git a/tests/Html/Editor/Fields/FieldTest.php b/tests/Html/Editor/Fields/FieldTest.php
new file mode 100644
index 0000000..bba6ef4
--- /dev/null
+++ b/tests/Html/Editor/Fields/FieldTest.php
@@ -0,0 +1,296 @@
+assertInstanceOf(Fields\Field::class, $field);
+ $this->assertEquals('Name', $field->label);
+ $this->assertEquals('name', $field->name);
+ $this->assertEquals('text', $field->getType());
+ }
+
+ #[Test]
+ public function it_can_set_properties()
+ {
+ $field = Fields\Field::make('name');
+
+ $field->label('Test');
+ $field->name('Test');
+ $field->data('Test');
+ $field->type('Test');
+
+ $this->assertEquals('Test', $field->label);
+ $this->assertEquals('Test', $field->name);
+ $this->assertEquals('Test', $field->data);
+ $this->assertEquals('Test', $field->getType());
+ }
+
+ #[Test]
+ public function it_can_create_belongs_to_field()
+ {
+ $field = Fields\BelongsTo::model(User::class, 'name');
+ $this->assertInstanceOf(Fields\BelongsTo::class, $field);
+ $this->assertEquals('select', $field->getType());
+ $this->assertEquals('user_id', $field->name);
+ $this->assertEquals('User', $field->label);
+ }
+
+ #[Test]
+ public function it_can_create_boolean_field()
+ {
+ $field = Fields\Boolean::make('name');
+ $this->assertInstanceOf(Fields\Boolean::class, $field);
+ $this->assertEquals('checkbox', $field->getType());
+ $this->assertEquals('name', $field->name);
+ $this->assertEquals('Name', $field->label);
+ $this->assertEquals(',', $field->separator);
+ $this->assertEquals([['label' => '', 'value' => 1]], $field->options);
+ }
+
+ #[Test]
+ public function it_can_create_date_field()
+ {
+ $field = Fields\Date::make('name');
+ $this->assertInstanceOf(Fields\Date::class, $field);
+ $this->assertEquals('datetime', $field->getType());
+ $this->assertEquals('name', $field->name);
+ $this->assertEquals('Name', $field->label);
+ $this->assertEquals('YYYY-MM-DD', $field->format);
+ }
+
+ #[Test]
+ public function it_can_create_datetime_field()
+ {
+ $field = Fields\DateTime::make('name');
+ $this->assertInstanceOf(Fields\DateTime::class, $field);
+ $this->assertEquals('datetime', $field->getType());
+ $this->assertEquals('name', $field->name);
+ $this->assertEquals('Name', $field->label);
+ $this->assertEquals('YYYY-MM-DD hh:mm a', $field->format);
+
+ $field->military();
+ $this->assertEquals('YYYY-MM-DD HH:mm', $field->format);
+
+ $min = now();
+ $field->minDate($min);
+ $date = $min->format('Y-m-d');
+ $this->assertEquals("new Date('$date')", $field->opts['minDate']);
+
+ $max = now();
+ $field->maxDate($max);
+ $date = $max->format('Y-m-d');
+ $this->assertEquals("new Date('$date')", $field->opts['maxDate']);
+
+ $field->showWeekNumber(false);
+ $this->assertEquals(false, $field->opts['showWeekNumber']);
+
+ $field->disableDays([1, 2, 3]);
+ $this->assertEquals([1, 2, 3], $field->opts['disableDays']);
+
+ $field->minutesIncrement(2);
+ $this->assertEquals(2, $field->opts['minutesIncrement']);
+
+ $field->secondsIncrement(2);
+ $this->assertEquals(2, $field->opts['secondsIncrement']);
+
+ $field->hoursAvailable([1, 2]);
+ $this->assertEquals([1, 2], $field->opts['hoursAvailable']);
+
+ $field->minutesAvailable([1, 2]);
+ $this->assertEquals([1, 2], $field->opts['minutesAvailable']);
+
+ $field->keyInput(false);
+ $this->assertEquals(false, $field->getAttributes()['keyInput']);
+
+ $field->displayFormat('LLL');
+ $this->assertEquals('LLL', $field->getAttributes()['displayFormat']);
+
+ $field->wireFormat('LLL');
+ $this->assertEquals('LLL', $field->getAttributes()['wireFormat']);
+ }
+
+ #[Test]
+ public function it_can_create_file_field()
+ {
+ $field = Fields\File::make('name');
+ $this->assertInstanceOf(Fields\File::class, $field);
+ $this->assertEquals('upload', $field->getType());
+ // TODO: add more file field test
+ }
+
+ #[Test]
+ public function it_can_create_hidden_field()
+ {
+ $field = Fields\Hidden::make('name');
+ $this->assertInstanceOf(Fields\Hidden::class, $field);
+ $this->assertEquals('hidden', $field->getType());
+ }
+
+ #[Test]
+ public function it_can_create_image_field()
+ {
+ $field = Fields\Image::make('name');
+ $this->assertInstanceOf(Fields\Image::class, $field);
+ $this->assertEquals('upload', $field->getType());
+ }
+
+ #[Test]
+ public function it_can_create_number_field()
+ {
+ $field = Fields\Number::make('name');
+ $this->assertInstanceOf(Fields\Number::class, $field);
+ $this->assertEquals('text', $field->getType());
+ }
+
+ #[Test]
+ public function it_can_create_password_field()
+ {
+ $field = Fields\Password::make('name');
+ $this->assertInstanceOf(Fields\Password::class, $field);
+ $this->assertEquals('password', $field->getType());
+ }
+
+ #[Test]
+ public function it_can_create_radio_field()
+ {
+ $field = Fields\Radio::make('name');
+ $this->assertInstanceOf(Fields\Radio::class, $field);
+ $this->assertEquals('radio', $field->getType());
+ }
+
+ #[Test]
+ public function it_can_create_read_only_field()
+ {
+ $field = Fields\ReadOnlyField::make('name');
+ $this->assertInstanceOf(Fields\ReadOnlyField::class, $field);
+ $this->assertEquals('readonly', $field->getType());
+ }
+
+ #[Test]
+ public function it_can_create_select_field()
+ {
+ $field = Fields\Select::make('name');
+ $this->assertInstanceOf(Fields\Select::class, $field);
+ $this->assertEquals('select', $field->getType());
+ }
+
+ #[Test]
+ public function it_can_create_select2_field()
+ {
+ $field = Fields\Select2::make('name')
+ ->allowClear()
+ ->optsPlaceholder('Test')
+ ->modelOptions(User::class, 'name')
+ ->ajax('/url');
+
+ $this->assertInstanceOf(Fields\Select2::class, $field);
+ $this->assertEquals('select2', $field->getType());
+ $this->assertEquals('/url', $field->opts['ajax']['url']);
+ $this->assertEquals('Test', $field->opts['placeholder']['text']);
+ $this->assertEquals('', $field->opts['placeholder']['id']);
+ $this->assertCount(20, $field->options);
+
+ $field->processResults('fn');
+ $this->assertEquals('fn', $field->opts['ajax']['processResults']);
+
+ $field->processPaginatedResults('username', 'user_id');
+ $this->assertEquals('/url', $field->opts['ajax']['url']);
+ $this->assertStringContainsString('e.text = e.username', $field->opts['ajax']['processResults']);
+ $this->assertStringContainsString('e.id = e.user_id', $field->opts['ajax']['processResults']);
+ $this->assertStringContainsString('data.results.map', $field->opts['ajax']['processResults']);
+
+ $field->processPaginatedResults('username', 'user_id', 'data');
+ $this->assertStringContainsString('data.data.map', $field->opts['ajax']['processResults']);
+
+ $field->placeholder('New Placeholder');
+ $this->assertEquals('New Placeholder', $field->opts['placeholder']['text']);
+
+ $field->ajaxData('fn');
+ $this->assertEquals('fn', $field->opts['ajax']['data']);
+
+ $field->ajaxData(['foo' => 'bar']);
+ $this->assertStringContainsString('params.foo = "bar"', $field->opts['ajax']['data']);
+
+ $field->ajaxDelay(200);
+ $this->assertEquals(200, $field->opts['ajax']['delay']);
+
+ $field->ajaxUrl('/test');
+ $this->assertEquals('/test', $field->opts['ajax']['url']);
+ }
+
+ #[Test]
+ public function it_can_create_text_field()
+ {
+ $field = Fields\Text::make('name')
+ ->attr('style', 'display: none;');
+
+ $this->assertInstanceOf(Fields\Text::class, $field);
+ $this->assertEquals('text', $field->getType());
+ $this->assertEquals('display: none;', $field->attr['style']);
+ }
+
+ #[Test]
+ public function it_can_create_textarea_field()
+ {
+ $field = Fields\TextArea::make('name');
+ $this->assertInstanceOf(Fields\TextArea::class, $field);
+ $this->assertEquals('textarea', $field->getType());
+
+ $field->rows(5);
+ $this->assertEquals('5', $field->attr['rows']);
+
+ $field->cols(5);
+ $this->assertEquals('5', $field->attr['cols']);
+ }
+
+ #[Test]
+ public function it_can_create_time_field()
+ {
+ $field = Fields\Time::make('name');
+ $this->assertInstanceOf(Fields\Time::class, $field);
+ $this->assertEquals('datetime', $field->getType());
+ $this->assertEquals('name', $field->name);
+ $this->assertEquals('Name', $field->label);
+ $this->assertEquals('hh:mm a', $field->format);
+ }
+
+ #[Test]
+ public function it_has_authorizations()
+ {
+ $field = Fields\Text::makeIf(true, 'name');
+ $this->assertEquals([
+ 'name' => 'name',
+ 'label' => 'Name',
+ 'type' => 'text',
+ ], $field->toArray());
+
+ $field = Fields\Text::makeIf(false, 'name');
+ $this->assertEquals([], $field->toArray());
+ }
+
+ #[Test]
+ public function it_can_be_serialized()
+ {
+ $field = Fields\Text::make('name')->data('user.name');
+
+ $this->assertEquals([
+ 'name' => 'name',
+ 'data' => 'user.name',
+ 'label' => 'Name',
+ 'type' => 'text',
+ ], $field->toArray());
+
+ $this->assertEquals('{"name":"name","label":"Name","type":"text","data":"user.name"}', $field->toJson());
+ }
+}
diff --git a/tests/Html/Editor/Fields/TagsTest.php b/tests/Html/Editor/Fields/TagsTest.php
new file mode 100644
index 0000000..da466e0
--- /dev/null
+++ b/tests/Html/Editor/Fields/TagsTest.php
@@ -0,0 +1,139 @@
+ajax('/tags');
+
+ $this->assertSame('/tags', $field->toArray()['ajax']);
+ }
+
+ #[Test]
+ public function it_can_set_tags_display(): void
+ {
+ $field = new Tags;
+ $field->display('display');
+
+ $this->assertSame('display', $field->toArray()['display']);
+ }
+
+ #[Test]
+ public function it_can_set_tags_escape_label_html(): void
+ {
+ $field = new Tags;
+ $field->escapeLabelHtml(true);
+
+ $this->assertTrue($field->toArray()['escapeLabelHtml']);
+ }
+
+ #[Test]
+ public function it_can_set_tags_i18n_props_directly(): void
+ {
+ $field = new Tags;
+ $field->addButton('Add Tag');
+ $this->assertSame('Add Tag', $field->toArray()['i18n']['addButton']);
+ }
+
+ #[Test]
+ public function it_can_set_tags_i18n(): void
+ {
+ $field = new Tags;
+ $field->i18n([
+ 'addButton' => 'Add',
+ 'inputPlaceholder' => 'Input',
+ 'noResults' => 'No Results',
+ 'title' => 'Title',
+ 'placeholder' => 'Placeholder',
+ ]);
+
+ $this->assertSame('Add', $field->toArray()['i18n']['addButton']);
+ $this->assertSame('Input', $field->toArray()['i18n']['inputPlaceholder']);
+ $this->assertSame('No Results', $field->toArray()['i18n']['noResults']);
+ $this->assertSame('Title', $field->toArray()['i18n']['title']);
+ $this->assertSame('Placeholder', $field->toArray()['i18n']['placeholder']);
+
+ $field->addButton('Add Button')
+ ->inputPlaceholder('Input Placeholder')
+ ->noResults('No Results X')
+ ->title('Title X')
+ ->placeholder('Placeholder X');
+
+ $this->assertSame('Add Button', $field->toArray()['i18n']['addButton']);
+ $this->assertSame('Input Placeholder', $field->toArray()['i18n']['inputPlaceholder']);
+ $this->assertSame('No Results X', $field->toArray()['i18n']['noResults']);
+ $this->assertSame('Title X', $field->toArray()['i18n']['title']);
+ $this->assertSame('Placeholder X', $field->toArray()['i18n']['placeholder']);
+ }
+
+ #[Test]
+ public function it_can_set_tags_type(): void
+ {
+ $field = new Tags;
+
+ $this->assertSame('tags', $field->toArray()['type']);
+ }
+
+ #[Test]
+ public function it_can_set_tags_limit(): void
+ {
+ $field = new Tags;
+ $field->limit(2);
+
+ $this->assertSame(2, $field->toArray()['limit']);
+ }
+
+ #[Test]
+ public function it_can_set_tags_multiple(): void
+ {
+ $field = new Tags;
+ $field->multiple();
+
+ $this->assertTrue($field->toArray()['multiple']);
+ }
+
+ #[Test]
+ public function it_can_set_tags_options(): void
+ {
+ $field = new Tags;
+ $field->options(['tag1', 'tag2']);
+
+ $this->assertSame(['tag1', 'tag2'], $field->toArray()['options']);
+
+ $field->options([
+ ['value' => 'tag1', 'label' => 'Tag 1'],
+ ['value' => 'tag2', 'label' => 'Tag 2'],
+ ]);
+
+ $this->assertSame([
+ ['value' => 'tag1', 'label' => 'Tag 1'],
+ ['value' => 'tag2', 'label' => 'Tag 2'],
+ ], $field->toArray()['options']);
+ }
+
+ #[Test]
+ public function it_can_set_tags_separator(): void
+ {
+ $field = new Tags;
+ $field->separator(',');
+
+ $this->assertSame(',', $field->toArray()['separator']);
+ }
+
+ #[Test]
+ public function it_can_set_tags_unique(): void
+ {
+ $field = new Tags;
+ $field->unique();
+
+ $this->assertTrue($field->toArray()['unique']);
+ }
+}
diff --git a/tests/Html/Extensions/SearchPaneTest.php b/tests/Html/Extensions/SearchPaneTest.php
new file mode 100644
index 0000000..48fd975
--- /dev/null
+++ b/tests/Html/Extensions/SearchPaneTest.php
@@ -0,0 +1,76 @@
+className('className')
+ ->header('header')
+ ->show()
+ ->name('name')
+ ->orthogonal('orthogonal')
+ ->hideTotal()
+ ->threshold(1)
+ ->hideCount()
+ ->filterChanged('filterChanged')
+ ->emptyMessage('emptyMessage')
+ ->dtOpts([])
+ ->controls()
+ ->columns([])
+ ->clear()
+ ->cascadePanes();
+
+ $this->assertInstanceOf(SearchPane::class, $pane);
+ $this->assertEquals('className', $pane->className);
+ $this->assertEquals('header', $pane->header);
+ $this->assertEquals(true, $pane->show);
+ $this->assertEquals('name', $pane->name);
+ $this->assertEquals('orthogonal', $pane->orthogonal);
+ $this->assertEquals(false, $pane->viewTotal);
+ $this->assertEquals(1, $pane->threshold);
+ $this->assertEquals(true, $pane->hideCount);
+ $this->assertEquals('filterChanged', $pane->filterChanged);
+ $this->assertEquals('emptyMessage', $pane->emptyMessage);
+ $this->assertEquals([], $pane->dtOpts);
+ $this->assertEquals(true, $pane->controls);
+ $this->assertEquals([], $pane->columns);
+ $this->assertEquals(true, $pane->clear);
+ $this->assertEquals(true, $pane->cascadePanes);
+
+ $pane->viewTotal();
+ $this->assertEquals(true, $pane->viewTotal);
+ }
+
+ #[Test]
+ public function it_has_options()
+ {
+ $pane = SearchPane::make()->options([1, 2, 3]);
+
+ $this->assertEquals([1, 2, 3], $pane->options);
+ $this->assertCount(3, $pane->options);
+
+ $pane->modelOptions(User::class, 'name');
+ $this->assertCount(20, $pane->options);
+ $this->assertIsArray($pane->options[0]);
+ $this->assertEquals(['value' => 1, 'label' => 'Record-1'], $pane->options[0]);
+ $this->assertEquals(['value' => 10, 'label' => 'Record-10'], $pane->options[9]);
+
+ $pane->tableOptions('users', 'name');
+ $this->assertCount(20, $pane->options);
+ $this->assertIsArray($pane->options[0]);
+ $this->assertEquals(['value' => 1, 'label' => 'Record-1'], $pane->options[0]);
+ $this->assertEquals(['value' => 10, 'label' => 'Record-10'], $pane->options[9]);
+ }
+}
diff --git a/tests/HtmlBuilderTest.php b/tests/HtmlBuilderTest.php
deleted file mode 100644
index cdf28fc..0000000
--- a/tests/HtmlBuilderTest.php
+++ /dev/null
@@ -1,231 +0,0 @@
-getHtmlBuilder([
- 'class' => 'table',
- 'id' => 'dataTableBuilder',
- ]);
-
- $builder->html->shouldReceive('attributes')->times(10)->andReturn('id="foo"');
-
- $builder->columns(['foo', 'bar' => ['data' => 'foo'], 'biz' => ['name' => 'baz']])
- ->addCheckbox(['id' => 'foo'])
- ->addColumn(['name' => 'id', 'data' => 'id', 'title' => 'Id'])
- ->addColumn(['data' => 'meh', 'title' => 'Muh'])
- ->add(new Column(['name' => 'a', 'data' => 'a', 'title' => 'A']))
- ->addAction(['title' => 'Options'])
- ->ajax('ajax-url')
- ->parameters(['bFilter' => false]);
- $table = $builder->table(['id' => 'foo'])->toHtml();
- $expected = '';
- $this->assertEquals($expected, $table);
-
- $builder->view->shouldReceive('make')->times(2)->andReturn($builder->view);
- $builder->config->shouldReceive('get')->times(2)->andReturn('datatables::script');
- $template = file_get_contents(__DIR__ . '/../src/resources/views/script.blade.php');
- $builder->view->shouldReceive('render')->times(2)->andReturn(trim($template));
- $builder->html->shouldReceive('attributes')->once()->andReturn();
-
- $script = $builder->scripts()->toHtml();
- $expected = '' . "\n";
- $this->assertEquals($expected, $script);
-
- $expected = '$(function(){window.{{ config(\'datatables-html.namespace\', \'LaravelDataTables\') }}=window.{{ config(\'datatables-html.namespace\', \'LaravelDataTables\') }}||{};window.{{ config(\'datatables-html.namespace\', \'LaravelDataTables\') }}["foo"]=$("#foo").DataTable({"serverSide":true,"processing":true,"ajax":"ajax-url","columns":[{"name":"foo","data":"foo","title":"Foo","orderable":true,"searchable":true},{"name":"foo","data":"foo","title":"Bar","orderable":true,"searchable":true},{"name":"baz","data":"biz","title":"Biz","orderable":true,"searchable":true},{"defaultContent":"","title":"","data":"checkbox","name":"checkbox","orderable":false,"searchable":false,"width":"10px","id":"foo"},{"name":"id","data":"id","title":"Id","orderable":true,"searchable":true},{"data":"meh","title":"Muh","orderable":true,"searchable":true,"name":"meh"},{"name":"a","data":"a","title":"A","orderable":true,"searchable":true},{"defaultContent":"","data":"action","name":"action","title":"Options","render":null,"orderable":false,"searchable":false}],"bFilter":false});});';
- $this->assertEquals($expected, $builder->generateScripts()->toHtml());
- }
-
- /**
- * @return \Mockery\MockInterface|\Yajra\DataTables\Html\Builder
- */
- protected function getHtmlBuilder($config = [])
- {
- $builder = app('datatables.html', $config);
-
- return $builder;
- }
-
- public function test_generate_table_html_with_empty_footer()
- {
- $builder = $this->getHtmlBuilder([
- 'class' => 'table',
- 'id' => 'dataTableBuilder',
- ]);
- $builder->html->shouldReceive('attributes')->times(8)->andReturn('id="foo"');
-
- $builder->columns(['foo', 'bar' => ['data' => 'foo']])
- ->addCheckbox(['id' => 'foo'])
- ->addColumn(['name' => 'id', 'data' => 'id', 'title' => 'Id'])
- ->add(new Column(['name' => 'a', 'data' => 'a', 'title' => 'A']))
- ->addAction(['title' => 'Options'])
- ->ajax('ajax-url')
- ->parameters(['bFilter' => false]);
- $table = $builder->table(['id' => 'foo'], true)->toHtml();
- $expected = '';
- $this->assertEquals($expected, $table);
-
- $builder->view->shouldReceive('make')->times(2)->andReturn($builder->view);
- $builder->config->shouldReceive('get')->times(2)->andReturn('datatables::script');
- $template = file_get_contents(__DIR__ . '/../src/resources/views/script.blade.php');
- $builder->view->shouldReceive('render')->times(2)->andReturn(trim($template));
- $builder->html->shouldReceive('attributes')->once()->andReturn();
-
- $script = $builder->scripts()->toHtml();
- $expected = '' . "\n";
- $this->assertEquals($expected, $script);
-
- $expected = '$(function(){window.{{ config(\'datatables-html.namespace\', \'LaravelDataTables\') }}=window.{{ config(\'datatables-html.namespace\', \'LaravelDataTables\') }}||{};window.{{ config(\'datatables-html.namespace\', \'LaravelDataTables\') }}["foo"]=$("#foo").DataTable({"serverSide":true,"processing":true,"ajax":"ajax-url","columns":[{"name":"foo","data":"foo","title":"Foo","orderable":true,"searchable":true},{"name":"foo","data":"foo","title":"Bar","orderable":true,"searchable":true},{"defaultContent":"","title":"","data":"checkbox","name":"checkbox","orderable":false,"searchable":false,"width":"10px","id":"foo"},{"name":"id","data":"id","title":"Id","orderable":true,"searchable":true},{"name":"a","data":"a","title":"A","orderable":true,"searchable":true},{"defaultContent":"","data":"action","name":"action","title":"Options","render":null,"orderable":false,"searchable":false}],"bFilter":false});});';
- $this->assertEquals($expected, $builder->generateScripts()->toHtml());
- }
-
- public function test_generate_table_html_with_footer_content()
- {
- $builder = $this->getHtmlBuilder([
- 'class' => 'table',
- 'id' => 'dataTableBuilder',
- ]);
- $builder->html->shouldReceive('attributes')->times(8)->andReturn('id="foo"');
-
- $builder->columns(['foo', 'bar' => ['data' => 'foo']])
- ->addCheckbox(['id' => 'foo', 'footer' => 'test'])
- ->addColumn(['name' => 'id', 'data' => 'id', 'title' => 'Id'])
- ->add(new Column(['name' => 'a', 'data' => 'a', 'title' => 'A']))
- ->addAction(['title' => 'Options'])
- ->ajax('ajax-url')
- ->parameters(['bFilter' => false]);
- $table = $builder->table(['id' => 'foo'], true)->toHtml();
- $expected = '';
- $this->assertEquals($expected, $table);
-
- $builder->view->shouldReceive('make')->times(2)->andReturn($builder->view);
- $builder->config->shouldReceive('get')->times(2)->andReturn('datatables::script');
- $template = file_get_contents(__DIR__ . '/../src/resources/views/script.blade.php');
- $builder->view->shouldReceive('render')->times(2)->andReturn(trim($template));
- $builder->html->shouldReceive('attributes')->once()->andReturn();
-
- $script = $builder->scripts()->toHtml();
- $expected = '' . "\n";
- $this->assertEquals($expected, $script);
-
- $expected = '$(function(){window.{{ config(\'datatables-html.namespace\', \'LaravelDataTables\') }}=window.{{ config(\'datatables-html.namespace\', \'LaravelDataTables\') }}||{};window.{{ config(\'datatables-html.namespace\', \'LaravelDataTables\') }}["foo"]=$("#foo").DataTable({"serverSide":true,"processing":true,"ajax":"ajax-url","columns":[{"name":"foo","data":"foo","title":"Foo","orderable":true,"searchable":true},{"name":"foo","data":"foo","title":"Bar","orderable":true,"searchable":true},{"defaultContent":"","title":"","data":"checkbox","name":"checkbox","orderable":false,"searchable":false,"width":"10px","id":"foo"},{"name":"id","data":"id","title":"Id","orderable":true,"searchable":true},{"name":"a","data":"a","title":"A","orderable":true,"searchable":true},{"defaultContent":"","data":"action","name":"action","title":"Options","render":null,"orderable":false,"searchable":false}],"bFilter":false});});';
- $this->assertEquals($expected, $builder->generateScripts()->toHtml());
- }
-
- public function test_generate_table_html_with_render_helpers()
- {
- $builder = $this->getHtmlBuilder([
- 'class' => 'table',
- 'id' => 'dataTableBuilder',
- ]);
-
- $builder->html->shouldReceive('attributes')->times(10)->andReturn('id="foo"');
-
- $builder->columns(['foo', 'bar' => ['data' => 'foo'], 'biz' => ['name' => 'baz']])
- ->addCheckbox(['id' => 'foo'])
- ->addColumn(['data' => '1.0000', 'title' => 'Num', 'render' => '$.fn.dataTable.render.number( ",", ".", 2, "" )'])
- ->addColumn(['data' => '
', 'title' => 'Tex', 'render' => '$.fn.dataTable.render.text()'])
- ->addAction(['title' => 'Options'])
- ->ajax('ajax-url')
- ->parameters(['bFilter' => false]);
- $table = $builder->table(['id' => 'foo'])->toHtml();
- $expected = '';
- $this->assertEquals($expected, $table);
-
- $builder->view->shouldReceive('make')->times(2)->andReturn($builder->view);
- $builder->config->shouldReceive('get')->times(2)->andReturn('datatables::script');
- $template = file_get_contents(__DIR__ . '/../src/resources/views/script.blade.php');
- $builder->view->shouldReceive('render')->times(2)->andReturn(trim($template));
- $builder->html->shouldReceive('attributes')->once()->andReturn();
-
- $script = $builder->scripts()->toHtml();
- $expected = '' . "\n";
- $this->assertEquals($expected, $script);
-
- $expected = '$(function(){window.{{ config(\'datatables-html.namespace\', \'LaravelDataTables\') }}=window.{{ config(\'datatables-html.namespace\', \'LaravelDataTables\') }}||{};window.{{ config(\'datatables-html.namespace\', \'LaravelDataTables\') }}["foo"]=$("#foo").DataTable({"serverSide":true,"processing":true,"ajax":"ajax-url","columns":[{"name":"foo","data":"foo","title":"Foo","orderable":true,"searchable":true},{"name":"foo","data":"foo","title":"Bar","orderable":true,"searchable":true},{"name":"baz","data":"biz","title":"Biz","orderable":true,"searchable":true},{"defaultContent":"","title":"","data":"checkbox","name":"checkbox","orderable":false,"searchable":false,"width":"10px","id":"foo"},{"data":"1.0000","title":"Num","render":"$.fn.dataTable.render.number( \",\", \".\", 2, \"\" )","orderable":true,"searchable":true,"name":"1.0000"},{"data":"
","title":"Tex","render":"$.fn.dataTable.render.text()","orderable":true,"searchable":true,"name":"
"},{"defaultContent":"","data":"action","name":"action","title":"Options","render":null,"orderable":false,"searchable":false}],"bFilter":false});});';
- $this->assertEquals($expected, $builder->generateScripts()->toHtml());
- }
-
- public function test_setting_table_attribute()
- {
- $builder = $this->getHtmlBuilder();
-
- $builder->setTableAttribute('attr', 'val');
-
- $this->assertEquals('val', $builder->getTableAttribute('attr'));
- }
-
- public function test_setting_table_id_attribute()
- {
- $builder = $this->getHtmlBuilder();
-
- $builder->setTableId('val');
-
- $this->assertEquals('val', $builder->getTableAttribute('id'));
- }
-
- public function test_settings_multiple_table_attributes()
- {
- $builder = $this->getHtmlBuilder();
-
- $builder->setTableAttribute(['prop1' => 'val1', 'prop2' => 'val2']);
-
- $this->assertEquals('val1', $builder->getTableAttribute('prop1'));
- $this->assertEquals('val2', $builder->getTableAttribute('prop2'));
- }
-
- public function test_getting_inexistent_table_attribute_throws()
- {
- $this->expectExceptionMessage('Table attribute \'boohoo\' does not exist.');
-
- $builder = $this->getHtmlBuilder();
-
- $builder->getTableAttribute('boohoo');
- }
-
- public function test_adding_table_class_attribute()
- {
- $builder = $this->getHtmlBuilder();
-
- $builder->addTableClass('foo');
- $this->assertEquals('foo', $builder->getTableAttribute('class'));
-
- $builder->addTableClass(' foo bar ');
- $this->assertEquals('foo bar', $builder->getTableAttribute('class'));
-
- $builder->addTableClass([' a-b ', 'foo c bar', 'key' => 'value']);
- $this->assertEquals('foo bar a-b c value', $builder->getTableAttribute('class'));
- }
-
- public function test_removing_table_class_attribute()
- {
- $builder = $this->getHtmlBuilder();
- $builder->setTableAttribute('class', ' foo bar a b c ');
-
- $builder->removeTableClass('bar');
- $this->assertEquals('foo a b c', $builder->getTableAttribute('class'));
-
- $builder->removeTableClass(' x c y ');
- $this->assertEquals('foo a b', $builder->getTableAttribute('class'));
-
- $builder->removeTableClass(['a' => ' b ', ' foo bar ']);
- $this->assertEquals('a', $builder->getTableAttribute('class'));
- }
-
- /**
- * @return \Yajra\DataTables\Factory
- */
- protected function getDataTables()
- {
- $factory = new Factory;
-
- return $factory;
- }
-}
diff --git a/tests/Models/Post.php b/tests/Models/Post.php
new file mode 100644
index 0000000..49f0df8
--- /dev/null
+++ b/tests/Models/Post.php
@@ -0,0 +1,21 @@
+belongsTo(User::class);
+ }
+}
diff --git a/tests/Models/Role.php b/tests/Models/Role.php
new file mode 100644
index 0000000..5a0b4bb
--- /dev/null
+++ b/tests/Models/Role.php
@@ -0,0 +1,16 @@
+belongsToMany(User::class);
+ }
+}
diff --git a/tests/Models/User.php b/tests/Models/User.php
new file mode 100644
index 0000000..81909d6
--- /dev/null
+++ b/tests/Models/User.php
@@ -0,0 +1,28 @@
+hasMany(Post::class);
+ }
+
+ public function roles(): BelongsToMany
+ {
+ return $this->belongsToMany(Role::class);
+ }
+
+ public function user(): MorphTo
+ {
+ return $this->morphTo();
+ }
+}
diff --git a/tests/TestCase.php b/tests/TestCase.php
new file mode 100644
index 0000000..09a82ee
--- /dev/null
+++ b/tests/TestCase.php
@@ -0,0 +1,129 @@
+set('app.key', 'base64:6pASQ5U2UYo+w6noM9hwOPeHJ5vGP+BNruyMtRA8FWY=');
+
+ $this->migrateDatabase();
+ $this->seedDatabase();
+ $this->setupViewAndBladeDirectory();
+ }
+
+ protected function migrateDatabase(): void
+ {
+ /** @var \Illuminate\Database\Schema\Builder $schemaBuilder */
+ $schemaBuilder = $this->app['db']->connection()->getSchemaBuilder();
+ if (! $schemaBuilder->hasTable('users')) {
+ $schemaBuilder->create('users', function (Blueprint $table) {
+ $table->increments('id');
+ $table->string('name');
+ $table->string('email');
+ $table->string('user_type')->nullable();
+ $table->unsignedInteger('user_id')->nullable();
+ $table->timestamps();
+ });
+ }
+ if (! $schemaBuilder->hasTable('posts')) {
+ $schemaBuilder->create('posts', function (Blueprint $table) {
+ $table->increments('id');
+ $table->string('title');
+ $table->unsignedInteger('user_id');
+ $table->timestamps();
+ $table->softDeletes();
+ });
+ }
+ if (! $schemaBuilder->hasTable('roles')) {
+ $schemaBuilder->create('roles', function (Blueprint $table) {
+ $table->increments('id');
+ $table->string('role');
+ $table->timestamps();
+ });
+ }
+ if (! $schemaBuilder->hasTable('role_user')) {
+ $schemaBuilder->create('role_user', function (Blueprint $table) {
+ $table->unsignedInteger('role_id');
+ $table->unsignedInteger('user_id');
+ $table->timestamps();
+ });
+ }
+ }
+
+ protected function seedDatabase(): void
+ {
+ $adminRole = Role::create(['role' => 'Administrator']);
+ $userRole = Role::create(['role' => 'User']);
+
+ collect(range(1, 20))->each(function ($i) use ($userRole) {
+ /** @var User $user */
+ $user = User::query()->create([
+ 'name' => 'Record-'.$i,
+ 'email' => 'Email-'.$i.'@example.com',
+ ]);
+
+ collect(range(1, 3))->each(function ($i) use ($user) {
+ $user->posts()->create([
+ 'title' => "User-{$user->id} Post-{$i}",
+ ]);
+ });
+
+ if ($i % 2) {
+ $user->roles()->attach(Role::all());
+ } else {
+ $user->roles()->attach($userRole);
+ }
+ });
+ }
+
+ /**
+ * Set up the environment.
+ *
+ * @param \Illuminate\Foundation\Application $app
+ */
+ protected function getEnvironmentSetUp($app): void
+ {
+ $app['config']->set('app.debug', true);
+ $app['config']->set('database.default', 'sqlite');
+ $app['config']->set('database.connections.sqlite', [
+ 'driver' => 'sqlite',
+ 'database' => ':memory:',
+ 'prefix' => '',
+ ]);
+ }
+
+ protected function getPackageProviders($app): array
+ {
+ return [
+ LivewireServiceProvider::class,
+ DataTablesServiceProvider::class,
+ HtmlServiceProvider::class,
+ ];
+ }
+
+ protected function getHtmlBuilder(): Builder
+ {
+ return app(Builder::class);
+ }
+
+ protected function setupViewAndBladeDirectory(): void
+ {
+ View::addLocation(__DIR__.'/TestComponents');
+ Blade::componentNamespace('Yajra\\DataTables\\Html\\Tests\\TestComponents', 'test');
+ }
+}
diff --git a/tests/TestComponents/TestInlineView.php b/tests/TestComponents/TestInlineView.php
new file mode 100644
index 0000000..a7f419a
--- /dev/null
+++ b/tests/TestComponents/TestInlineView.php
@@ -0,0 +1,15 @@
+Test Inline View
+ blade;
+ }
+}
diff --git a/tests/TestComponents/TestLivewire.php b/tests/TestComponents/TestLivewire.php
new file mode 100644
index 0000000..36277b4
--- /dev/null
+++ b/tests/TestComponents/TestLivewire.php
@@ -0,0 +1,15 @@
+test livewire
+ blade;
+ }
+}
diff --git a/tests/TestComponents/TestView.php b/tests/TestComponents/TestView.php
new file mode 100644
index 0000000..7651711
--- /dev/null
+++ b/tests/TestComponents/TestView.php
@@ -0,0 +1,14 @@
+Test blade file
diff --git a/tests/helper.php b/tests/helper.php
deleted file mode 100644
index 95fe360..0000000
--- a/tests/helper.php
+++ /dev/null
@@ -1,61 +0,0 @@
-shouldReceive('get')->andReturn($config);
-
- return new Builder(
- $configMock,
- m::mock('Illuminate\Contracts\View\Factory'),
- m::mock('Collective\Html\HtmlBuilder')
- );
- case 'config':
- return new Config;
- case 'view':
- return m::mock('Illuminate\Contracts\View\Factory', function ($mock) {
- $mock->shouldReceive('exists')->andReturn(false);
- });
- }
-
- return new Factory();
-}
-
-function view($view = null, array $data = [])
-{
- if (! $view) {
- return new BladeView();
- }
-
- return (new BladeView())->exists($view);
-}
-
-/**
- * Blade View Stub.
- */
-class BladeView
-{
- public function exists($view)
- {
- return false;
- }
-}
-
-class Config
-{
- public function get($key)
- {
- $keys = explode('.', $key);
- $config = require __DIR__ . '/../src/config/config.php';
- $config['builders'] = Arr::add($config['builders'], 'Mockery_8_Illuminate_Database_Query_Builder', 'query');
-
- return $config[$keys[1]];
- }
-}