From bf689eb4568362de60f34e7f73239690f5731c6d Mon Sep 17 00:00:00 2001 From: Pascal Baljet Date: Wed, 5 Jan 2022 10:03:41 +0100 Subject: [PATCH] Default wire setting (#76) --- CHANGELOG.md | 5 ++ README.md | 4 +- config/config.php | 3 + src/Components/Component.php | 4 ++ src/FormDataBinder.php | 15 ++++ tests/Feature/LivewireTest.php | 69 +++++++++++++++++++ ...livewire-form-default-wired-lazy.blade.php | 14 ++++ ...form-default-wired-with-override.blade.php | 14 ++++ .../livewire-form-default-wired.blade.php | 14 ++++ tests/Unit/FormDataBinderTest.php | 2 +- 10 files changed, 142 insertions(+), 2 deletions(-) create mode 100644 tests/Feature/views/livewire-form-default-wired-lazy.blade.php create mode 100644 tests/Feature/views/livewire-form-default-wired-with-override.blade.php create mode 100644 tests/Feature/views/livewire-form-default-wired.blade.php diff --git a/CHANGELOG.md b/CHANGELOG.md index 60f65c0..23898c7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,11 @@ All notable changes to `laravel-form-components` will be documented in this file +## 3.5.0 - 2022-01-05 + +- Added `default_wire` configuration +- Fix for overriding `wire:model` attribute + ## 3.4.0 - 2022-01-04 - Added `tailwind-forms-simple` views diff --git a/README.md b/README.md index 065a25f..f9e04ec 100644 --- a/README.md +++ b/README.md @@ -266,7 +266,7 @@ class ContactForm extends Component } ``` -Normally you would use a `wire:model` attribute to bind a component property with a form element. By using the `@wire` directive, this package will automatically use the `wire:model` attribute instead of the `name` attribute. +Normally you would use a `wire:model` attribute to bind a component property with a form element. By using the `@wire` directive, this package will automatically add the `wire:model` attribute. ```blade @@ -289,6 +289,8 @@ Additionally, you can pass an optional modifier to the `@wire` directive. This f ``` +It's also possible to use the `wire:model` attribute by default. You may set the `default_wire` configuration setting to `true` or a modifier like `debounce.500ms`. This way, you don't need the `@wire` and `@endwire` directives in your views. You may still override the default setting by manually adding the `wire:model` attribute to a form element. + ### Select elements Besides the `name` attribute, the `select` element has a required `options` attribute, which should be a simple *key-value* array. diff --git a/config/config.php b/config/config.php index 638a58e..88f4023 100644 --- a/config/config.php +++ b/config/config.php @@ -10,6 +10,9 @@ 'use_eloquent_date_casting' => false, + /** bool | string */ + 'default_wire' => false, + 'components' => [ 'form' => [ 'view' => 'form-components::{framework}.form', diff --git a/src/Components/Component.php b/src/Components/Component.php index c62df1a..7c49ad9 100644 --- a/src/Components/Component.php +++ b/src/Components/Component.php @@ -36,6 +36,10 @@ public function render() */ public function isWired(): bool { + if ($this->attributes && count($this->attributes->whereStartsWith('wire:model')->getIterator())) { + return false; + } + return app(FormDataBinder::class)->isWired(); } diff --git a/src/FormDataBinder.php b/src/FormDataBinder.php index 99c3ddb..378905f 100644 --- a/src/FormDataBinder.php +++ b/src/FormDataBinder.php @@ -16,6 +16,11 @@ class FormDataBinder */ private $wire = false; + /** + * Whether the default wire has been verified once. + */ + private $verifiedDefaultWire = false; + /** * Bind a target to the current instance * @@ -54,6 +59,16 @@ public function pop(): void */ public function isWired(): bool { + if (!$this->verifiedDefaultWire) { + $this->verifiedDefaultWire = true; + + $defaultWire = config('form-components.default_wire'); + + if ($defaultWire !== false) { + $this->wire = $defaultWire; + } + } + return $this->wire !== false; } diff --git a/tests/Feature/LivewireTest.php b/tests/Feature/LivewireTest.php index 52ecca2..4378ed9 100644 --- a/tests/Feature/LivewireTest.php +++ b/tests/Feature/LivewireTest.php @@ -41,6 +41,30 @@ public function render() } } +class FormComponentDefaultWired extends FormComponent +{ + public function render() + { + return view('livewire-form-default-wired'); + } +} + +class FormComponentDefaultWiredModifier extends FormComponent +{ + public function render() + { + return view('livewire-form-default-wired-lazy'); + } +} + +class FormComponentDefaultWiredWithOverride extends FormComponent +{ + public function render() + { + return view('livewire-form-default-wired-with-override'); + } +} + class LivewireTest extends TestCase { /** @test */ @@ -96,4 +120,49 @@ public function it_can_add_a_modifier_to_the_wire_directive() ->assertSeeHtml('The checkbox must be accepted') ->assertSeeHtml('The radio must be accepted'); } + + /** @test */ + public function it_can_wire_by_default() + { + config(['form-components.default_wire' => true]); + + $component = Livewire::test(FormComponentDefaultWired::class); + + $component->assertSeeHtml('wire:model="input"') + ->assertSeeHtml('wire:model="textarea"') + ->assertSeeHtml('wire:model="select"') + ->assertSeeHtml('wire:model="multi_select"') + ->assertSeeHtml('wire:model="checkbox"') + ->assertSeeHtml('wire:model="radio"'); + } + + /** @test */ + public function it_can_wire_by_default_with_a_modifier() + { + config(['form-components.default_wire' => 'debounce.1000ms']); + + $component = Livewire::test(FormComponentDefaultWiredModifier::class); + + $component->assertSeeHtml('wire:model.debounce.1000ms="input"') + ->assertSeeHtml('wire:model.debounce.1000ms="textarea"') + ->assertSeeHtml('wire:model.debounce.1000ms="select"') + ->assertSeeHtml('wire:model.debounce.1000ms="multi_select"') + ->assertSeeHtml('wire:model.debounce.1000ms="checkbox"') + ->assertSeeHtml('wire:model.debounce.1000ms="radio"'); + } + + /** @test */ + public function it_can_wire_by_default_but_still_override_the_value() + { + config(['form-components.default_wire' => true]); + + $component = Livewire::test(FormComponentDefaultWiredWithOverride::class); + + $component->assertSeeHtml('wire:model="input"') + ->assertSeeHtml('wire:model="textarea"') + ->assertDontSeeHtml('wire:model="select"') + ->assertSeeHtml('wire:model.debounce.1000ms="multi_select"') + ->assertSeeHtml('wire:model="checkbox"') + ->assertSeeHtml('wire:model="radio"'); + } } diff --git a/tests/Feature/views/livewire-form-default-wired-lazy.blade.php b/tests/Feature/views/livewire-form-default-wired-lazy.blade.php new file mode 100644 index 0000000..6630030 --- /dev/null +++ b/tests/Feature/views/livewire-form-default-wired-lazy.blade.php @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/tests/Feature/views/livewire-form-default-wired-with-override.blade.php b/tests/Feature/views/livewire-form-default-wired-with-override.blade.php new file mode 100644 index 0000000..1282130 --- /dev/null +++ b/tests/Feature/views/livewire-form-default-wired-with-override.blade.php @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/tests/Feature/views/livewire-form-default-wired.blade.php b/tests/Feature/views/livewire-form-default-wired.blade.php new file mode 100644 index 0000000..6630030 --- /dev/null +++ b/tests/Feature/views/livewire-form-default-wired.blade.php @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/tests/Unit/FormDataBinderTest.php b/tests/Unit/FormDataBinderTest.php index b1dd660..b9953a2 100644 --- a/tests/Unit/FormDataBinderTest.php +++ b/tests/Unit/FormDataBinderTest.php @@ -2,8 +2,8 @@ namespace ProtoneMedia\LaravelFormComponents\Tests\Unit; -use PHPUnit\Framework\TestCase; use ProtoneMedia\LaravelFormComponents\FormDataBinder; +use ProtoneMedia\LaravelFormComponents\Tests\TestCase; class FormDataBinderTest extends TestCase {