From 76f776b642eaff0eae079b6a01ff5eae2384f4d9 Mon Sep 17 00:00:00 2001 From: Peter Elmered Date: Wed, 24 Jul 2024 16:11:30 +0200 Subject: [PATCH 1/4] Add support for setting symbol placement on MoneyInput + add support for symbolPlacement=none --- src/Forms/Components/MoneyInput.php | 35 +++++++++++++++++++++-------- src/HasMoneyAttributes.php | 1 + 2 files changed, 27 insertions(+), 9 deletions(-) diff --git a/src/Forms/Components/MoneyInput.php b/src/Forms/Components/MoneyInput.php index aa0c1b8..697fdcf 100644 --- a/src/Forms/Components/MoneyInput.php +++ b/src/Forms/Components/MoneyInput.php @@ -15,6 +15,8 @@ class MoneyInput extends TextInput { use HasMoneyAttributes; + protected string $symbolPlacement; + protected function setUp(): void { parent::setUp(); @@ -52,21 +54,20 @@ protected function setUp(): void protected function prepare(): void { - $symbolPlacement = Config::get('filament-money-field.form_currency_symbol_placement', 'before'); - + $symbolPlacement = $this->getSymbolPlacement(); $getCurrencySymbol = function (MoneyInput $component) { - return MoneyFormatter::getFormattingRules($component->getLocale())->currencySymbol; + return MoneyFormatter::getFormattingRules($component->getLocale(), $component->getCurrency())->currencySymbol; }; - if ($symbolPlacement === 'before') { - $this->prefix($getCurrencySymbol); - } else { - $this->suffix($getCurrencySymbol); - } + match ($symbolPlacement) { + 'before' => $this->prefix($getCurrencySymbol), + 'after' => $this->suffix($getCurrencySymbol), + 'none' => null, + }; if (config('filament-money-field.use_input_mask')) { $this->mask(function (MoneyInput $component) { - $formattingRules = MoneyFormatter::getFormattingRules($component->getLocale()); + $formattingRules = MoneyFormatter::getFormattingRules($component->getLocale(), $component->getCurrency()); return RawJs::make( strtr( @@ -82,6 +83,22 @@ protected function prepare(): void } } + public function getSymbolPlacement() + { + return $this->symbolPlacement ?? config('filament-money-field.default_symbol_placement'); + } + + public function symbolPlacement(string|Closure|null $symbolPlacement = null): static + { + $this->symbolPlacement = $this->evaluate($symbolPlacement); + + if (! in_array($this->symbolPlacement, ['before', 'after', 'none'])) { + throw new \InvalidArgumentException('Symbol placement must be either "before", "after" or "none".'); + } + + return $this; + } + public function minValue(mixed $value): static { $this->rule(new MinValueRule((int) $this->evaluate($value), $this)); diff --git a/src/HasMoneyAttributes.php b/src/HasMoneyAttributes.php index 504be4d..537ae6e 100644 --- a/src/HasMoneyAttributes.php +++ b/src/HasMoneyAttributes.php @@ -56,6 +56,7 @@ public function locale(string|Closure|null $locale = null): static return $this; } + public function decimals(int|Closure $decimals): static { $this->decimals = $this->evaluate($decimals); From f741db815bc0dd34cacd6b4615cb8fc536301a03 Mon Sep 17 00:00:00 2001 From: Peter Elmered Date: Wed, 24 Jul 2024 16:13:07 +0200 Subject: [PATCH 2/4] Change name of symbolPlacement none to hidden --- config/filament-money-field.php | 2 +- src/Forms/Components/MoneyInput.php | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/config/filament-money-field.php b/config/filament-money-field.php index ac74b37..e60ce0a 100644 --- a/config/filament-money-field.php +++ b/config/filament-money-field.php @@ -59,7 +59,7 @@ | Currency symbol placement |--------------------------------------------------------------------------- | - | Where the dunit should be on form fields. Options are 'before' (prefix), 'after' (suffix) or 'none'. + | Where the dunit should be on form fields. Options are 'before' (prefix), 'after' (suffix) or 'hidden'. | Note: In most non-English speaking European countries, | the currency symbol is after the amount and is preceded by a space (as in "10 €") | diff --git a/src/Forms/Components/MoneyInput.php b/src/Forms/Components/MoneyInput.php index 697fdcf..3670402 100644 --- a/src/Forms/Components/MoneyInput.php +++ b/src/Forms/Components/MoneyInput.php @@ -62,7 +62,7 @@ protected function prepare(): void match ($symbolPlacement) { 'before' => $this->prefix($getCurrencySymbol), 'after' => $this->suffix($getCurrencySymbol), - 'none' => null, + 'hidden' => null, }; if (config('filament-money-field.use_input_mask')) { @@ -92,8 +92,8 @@ public function symbolPlacement(string|Closure|null $symbolPlacement = null): st { $this->symbolPlacement = $this->evaluate($symbolPlacement); - if (! in_array($this->symbolPlacement, ['before', 'after', 'none'])) { - throw new \InvalidArgumentException('Symbol placement must be either "before", "after" or "none".'); + if (! in_array($this->symbolPlacement, ['before', 'after', 'hidden'])) { + throw new \InvalidArgumentException('Symbol placement must be either "before", "after" or "hidden".'); } return $this; From a35c796ee7cd1ad03e47343ec7a65b933b4b58cf Mon Sep 17 00:00:00 2001 From: Peter Elmered Date: Wed, 24 Jul 2024 16:41:33 +0200 Subject: [PATCH 3/4] Fixes for symbolPlacement + add tests --- src/Forms/Components/MoneyInput.php | 10 ++--- tests/FormInputTest.php | 66 ++++++++++++++++++++++++++--- 2 files changed, 66 insertions(+), 10 deletions(-) diff --git a/src/Forms/Components/MoneyInput.php b/src/Forms/Components/MoneyInput.php index 3670402..7e7a36d 100644 --- a/src/Forms/Components/MoneyInput.php +++ b/src/Forms/Components/MoneyInput.php @@ -15,7 +15,7 @@ class MoneyInput extends TextInput { use HasMoneyAttributes; - protected string $symbolPlacement; + protected ?string $symbolPlacement = null; protected function setUp(): void { @@ -60,9 +60,9 @@ protected function prepare(): void }; match ($symbolPlacement) { - 'before' => $this->prefix($getCurrencySymbol), - 'after' => $this->suffix($getCurrencySymbol), - 'hidden' => null, + 'before' => $this->prefix($getCurrencySymbol)->suffix(null), + 'after' => $this->suffix($getCurrencySymbol)->prefix(null), + 'hidden' => $this->suffix(null)->prefix(null), }; if (config('filament-money-field.use_input_mask')) { @@ -85,7 +85,7 @@ protected function prepare(): void public function getSymbolPlacement() { - return $this->symbolPlacement ?? config('filament-money-field.default_symbol_placement'); + return $this->symbolPlacement ?? config('filament-money-field.form_currency_symbol_placement', 'before'); } public function symbolPlacement(string|Closure|null $symbolPlacement = null): static diff --git a/tests/FormInputTest.php b/tests/FormInputTest.php index bb11704..d55d125 100644 --- a/tests/FormInputTest.php +++ b/tests/FormInputTest.php @@ -49,10 +49,26 @@ public function testNonNumericState(): void $component->getState(); } - public function testCurrencySymbolPlacementAfter() + public function testCurrencySymbolPlacementAfterInGlobalConfig() { config(['filament-money-field.form_currency_symbol_placement' => 'after']); + $component = ComponentContainer::make(FormTestComponent::make()) + ->statePath('data') + ->components([ + MoneyInput::make('price'), + ])->fill(['price' => 20]); + + /** @var MoneyInput $field */ + $field = $component->getComponent('data.price'); + $this->assertEquals('$', $field->getSuffixLabel()); + $this->assertNull($field->getPrefixLabel()); + } + + public function testCurrencySymbolPlacementBeforeInGlobalConfig() + { + config(['filament-money-field.form_currency_symbol_placement' => 'before']); + $component = ComponentContainer::make(FormTestComponent::make()) ->statePath('data') ->components([ @@ -60,13 +76,13 @@ public function testCurrencySymbolPlacementAfter() ])->fill(['price' => 20]); $field = $component->getComponent('data.price'); - $this->assertEquals('$', $field->getSuffixLabel()); - $this->assertNull($field->getPrefixLabel()); + $this->assertEquals('$', $field->getPrefixLabel()); + $this->assertNull($field->getSuffixLabel()); } - public function testCurrencySymbolPlacementBefore() + public function testCurrencySymbolPlacementHiddenInGlobalConfig() { - config(['filament-money-field.form_currency_symbol_placement' => 'before']); + config(['filament-money-field.form_currency_symbol_placement' => 'hidden']); $component = ComponentContainer::make(FormTestComponent::make()) ->statePath('data') @@ -74,11 +90,51 @@ public function testCurrencySymbolPlacementBefore() MoneyInput::make('price'), ])->fill(['price' => 20]); + $field = $component->getComponent('data.price'); + $this->assertNull($field->getPrefixLabel()); + $this->assertNull($field->getSuffixLabel()); + } + + public function testCurrencySymbolPlacementAfterOnField() + { + $component = ComponentContainer::make(FormTestComponent::make()) + ->statePath('data') + ->components([ + MoneyInput::make('price')->symbolPlacement('after'), + ])->fill(['price' => 20]); + + $field = $component->getComponent('data.price'); + //dd($field); + $this->assertEquals('$', $field->getSuffixLabel()); + $this->assertNull($field->getPrefixLabel()); + } + + public function testCurrencySymbolPlacementBeforeOnField() + { + $component = ComponentContainer::make(FormTestComponent::make()) + ->statePath('data') + ->components([ + MoneyInput::make('price')->symbolPlacement('before'), + ])->fill(['price' => 20]); + $field = $component->getComponent('data.price'); $this->assertEquals('$', $field->getPrefixLabel()); $this->assertNull($field->getSuffixLabel()); } + public function testCurrencySymbolPlacementHiddenOnField() + { + $component = ComponentContainer::make(FormTestComponent::make()) + ->statePath('data') + ->components([ + MoneyInput::make('price')->symbolPlacement('hidden'), + ])->fill(['price' => 20]); + + $field = $component->getComponent('data.price'); + $this->assertNull($field->getPrefixLabel()); + $this->assertNull($field->getSuffixLabel()); + } + public function testInputMask() { config(['filament-money-field.use_input_mask' => true]); From cb84835799ea09a05071b22b500eaa0a80d378f1 Mon Sep 17 00:00:00 2001 From: Peter Elmered Date: Wed, 24 Jul 2024 16:43:10 +0200 Subject: [PATCH 4/4] Add symbol placement example to readme --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 582c193..e784dc9 100644 --- a/README.md +++ b/README.md @@ -135,6 +135,7 @@ MoneyInput::make('price') ->maxValue(10000) // Add min and max value (in minor units, i.e. cents) to the input field. In this case no values over 100 ->step(100) // Step value for the input field. In this case only multiples of 100 are allowed. ->decimals(0) + ->getSymbolPlacement('after'), // Possible options: 'after', 'before', 'none'. Defaults to 'before' ``` ### Table column