Skip to content

Commit

Permalink
Merge pull request #42 from ariaieboy/41-add-textinputcolumn-currency…
Browse files Browse the repository at this point in the history
…mask-support

41 add textinputcolumn currencymask support
  • Loading branch information
ariaieboy authored Sep 22, 2024
2 parents cfaa188 + 133db5e commit 9f6ae72
Show file tree
Hide file tree
Showing 4 changed files with 181 additions and 9 deletions.
7 changes: 7 additions & 0 deletions ide-helper.stubs.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,13 @@ public function currency(string | Closure | null $currency = null, bool $shouldC
return $this;
}
}
class TextInputColumn
{
public function currencyMask($thousandSeparator = ',', $decimalSeparator = '.', $precision = 2): self
{
return $this;
}
}
}

namespace Filament\Forms\Components {
Expand Down
27 changes: 18 additions & 9 deletions resources/views/currency-mask.blade.php
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
@php
$datalistOptions = $getDatalistOptions();
$extraAlpineAttributes = $getExtraAlpineAttributes();
$hasInlineLabel = $hasInlineLabel();
$id = $getId();
$isConcealed = $isConcealed();
$isDisabled = $isDisabled();
$isLive = $isLive();
$isLiveOnBlur = $isLiveOnBlur();
$isLiveDebounced = $isLiveDebounced();
$liveDebounce = $getLiveDebounce();
$isPasswordRevealable = $isPasswordRevealable();
$isPrefixInline = $isPrefixInline();
$isSuffixInline = $isSuffixInline();
$mask = $getMask();
Expand All @@ -31,21 +29,31 @@
},
updateMasked(){
if(this.input !== undefined && typeof Number(this.input) === 'number') {
if(this.masked?.replaceAll('$thousandSeparator','').replaceAll('$decimalSeparator','.') !== this.input){
if(this.masked?.toString().replaceAll('$thousandSeparator','').replaceAll('$decimalSeparator','.') !== this.input){
this.masked = this.input?.toString().replaceAll('.','$decimalSeparator');
}
}
},
updateInput(value, oldValue){
if(value?.replaceAll('$thousandSeparator','').replaceAll('$decimalSeparator','.') !== oldValue?.replaceAll('$thousandSeparator','').replaceAll('$decimalSeparator','.')){
this.input = this.masked?.replaceAll('$thousandSeparator','').replaceAll('$decimalSeparator','.');
if(value?.toString().replaceAll('$thousandSeparator','').replaceAll('$decimalSeparator','.') !== oldValue?.toString().replaceAll('$thousandSeparator','').replaceAll('$decimalSeparator','.')){
this.input = this.masked?.toString().replaceAll('$thousandSeparator','').replaceAll('$decimalSeparator','.');
}
}
}
JS;
@endphp
<x-dynamic-component :component="$getFieldWrapperView()" :field="$field">
<x-dynamic-component
:component="$getFieldWrapperView()"
:field="$field">
<x-slot
name="label"
@class([
'sm:pt-1.5' => $hasInlineLabel,
])
>
{{ $getLabel() }}
</x-slot>
<x-filament::input.wrapper
:disabled="$isDisabled"
:inline-prefix="$isPrefixInline"
Expand All @@ -56,11 +64,12 @@
:suffix="$suffixLabel"
:suffix-actions="$suffixActions"
:suffix-icon="$suffixIcon"
:suffix-icon-color="$getSuffixIconColor()"
:valid="! $errors->has($statePath)"
class="fi-fo-text-input"
:attributes="
\Filament\Support\prepare_inherited_attributes($getExtraAttributeBag())
->class(['overflow-hidden'])
->class(['fi-fo-text-input overflow-hidden'])
"
>
<x-filament::input
Expand Down
147 changes: 147 additions & 0 deletions resources/views/text-input-column.blade.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
@php
use Filament\Support\Enums\Alignment;
$isDisabled = $isDisabled();
$state = $getState();
$mask = $getMask();
$alignment = $getAlignment() ?? Alignment::Start;
if (! $alignment instanceof Alignment) {
$alignment = filled($alignment) ? (Alignment::tryFrom($alignment) ?? $alignment) : null;
}
if (filled($mask)) {
$type = 'text';
} else {
$type = $getType();
}
$xmask = "\$money(\$input,'$decimalSeparator','$thousandSeparator',$precision)";
$xchange = <<<JS
isLoading = true
const response = await \$wire.updateTableColumnState(
name,
recordKey,
\$event.target.value.toString()?.replaceAll('$thousandSeparator','').replaceAll('$decimalSeparator','.'),
)
error = response?.error ?? undefined
if (! error) {
if(state?.toString().replaceAll('$thousandSeparator','').replaceAll('$decimalSeparator','.') !== response.toString()){
state = response
}
}
isLoading = false
JS;
@endphp
<div
x-data="{
error: undefined,
isEditing: false,
isLoading: false,
name: @js($getName()),
recordKey: @js($recordKey),
state: @js($state),
}"
x-init="
() => {
Livewire.hook('commit', ({ component, commit, succeed, fail, respond }) => {
succeed(({ snapshot, effect }) => {
$nextTick(() => {
if (component.id !== @js($this->getId())) {
return
}
if (isEditing) {
return
}
if (! $refs.newState) {
return
}
let newState = $refs.newState.value?.toString().replaceAll('{{$thousandSeparator}}','').replaceAll('{{$decimalSeparator}}','.')
if (state?.toString().replaceAll('{{$thousandSeparator}}','').replaceAll('{{$decimalSeparator}}','.') === newState) {
return
}
state = newState
})
})
})
}
"
{{
$attributes
->merge($getExtraAttributes(), escape: false)
->class([
'fi-ta-text-input',
'px-3 py-4' => ! $isInline(),
])
}}
>
<input
type="hidden"
value="{{ str($state)->replace('"', '\\"')->replace(',','') }}"
x-ref="newState"
/>
<x-filament::input.wrapper
:alpine-disabled="'isLoading || ' . \Illuminate\Support\Js::from($isDisabled)"
alpine-valid="error === undefined"
x-tooltip="
error === undefined
? false
: {
content: error,
theme: $store.theme,
}
"
x-on:click.stop=""
>
{{-- format-ignore-start --}}
<x-filament::input
:disabled="$isDisabled"
:input-mode="$getInputMode()"
:placeholder="$getPlaceholder()"
:step="$getStep()"
:type="$type"
:x-bind:disabled="$isDisabled ? null : 'isLoading'"
x-model="state"
x-on:blur="isEditing = false"
x-on:focus="isEditing = true"
:attributes="
\Filament\Support\prepare_inherited_attributes(
$getExtraInputAttributeBag()
->merge([
'x-on:change' . ($type === 'number' ? '.debounce.1s' : null) => $xchange,
'x-mask:dynamic'=> $xmask,
])
->class([
match ($alignment) {
Alignment::Start => 'text-start',
Alignment::Center => 'text-center',
Alignment::End => 'text-end',
Alignment::Left => 'text-left',
Alignment::Right => 'text-right',
Alignment::Justify, Alignment::Between => 'text-justify',
default => $alignment,
},
])
)
"
/>
{{-- format-ignore-end --}}
</x-filament::input.wrapper>
</div>
9 changes: 9 additions & 0 deletions src/FilamentCurrencyServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
use Filament\Tables\Columns\Column;
use Filament\Tables\Columns\Summarizers;
use Filament\Tables\Columns\TextColumn;
use Filament\Tables\Columns\TextInputColumn;
use Spatie\LaravelPackageTools\Package;
use Spatie\LaravelPackageTools\PackageServiceProvider;

Expand Down Expand Up @@ -64,7 +65,15 @@ public function bootingPackage(): void

return $this;
});
TextInputColumn::macro('currencyMask',function ($thousandSeparator = ',', $decimalSeparator = '.', $precision = 2): TextInputColumn {
/**
* @var TextInput $this
*/
$this->view = 'filament-currency::text-input-column';
$this->viewData(compact('thousandSeparator', 'decimalSeparator', 'precision'));

return $this;
});
Summarizers\Sum::macro('currency', function (string | Closure | null $currency = null, bool $shouldConvert = false) use ($formatter): Summarizers\Sum {
/**
* @var Summarizers\Sum $this
Expand Down

0 comments on commit 9f6ae72

Please sign in to comment.