Skip to content

Commit

Permalink
First draft
Browse files Browse the repository at this point in the history
  • Loading branch information
afonic committed Nov 4, 2024
1 parent 0acbeb8 commit 61f685e
Show file tree
Hide file tree
Showing 7 changed files with 433 additions and 0 deletions.
1 change: 1 addition & 0 deletions resources/lang/en/ui.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@
'default' => 'Default',
'all' => 'All',
'value' => 'Value',
'to' => 'to',
];
73 changes: 73 additions & 0 deletions resources/views/livewire/filters/lf-dual-range.blade.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
<div>
<div
x-data="dualRange({
initialMin: @entangle('selectedMin'),
initialMax: @entangle('selectedMax'),
step: {{ $step }},
min: {{ $min }},
max: {{ $max }},
format: '{{ $format }}',
minRange: {{ $minRange }}
})"
class="w-full my-8"
>
<div class="relative">
<div x-ref="slider" class="w-[93%] mx-auto"></div>
<div class="flex justify-center mt-3">
<span class="font-bold" x-text="min"></span>
<span class="mx-2">{{ __('statamic-livewire-filters::ui.to') }}</span>
<span class="font-bold" x-text="max"></span>
</div>
</div>
</div>
</div>

@script
<script>
Alpine.data('dualRange', ({ initialMin, initialMax, step, min, max, format, minRange }) => ({
min: initialMin,
max: initialMax,
init() {
const slider = this.$refs.slider;
console.log(window);
window.noUiSlider.create(slider, {
start: [this.min, this.max],
connect: true,
step: step,
range: {
'min': min,
'max': max
},
format: {
to: (value) => {
return format === 'date'
? new Date(value).getFullYear()
: Math.round(value);
},
from: (value) => {
return format === 'date'
? new Date(value, 0).getTime()
: parseFloat(value);
}
}
});
slider.noUiSlider.on('update', (values) => {
this.min = values[0];
this.max = values[1];
});
slider.noUiSlider.on('slide', (values, handle) => {
if (handle === 0 && (values[1] - values[0]) < minRange) {
slider.noUiSlider.set([values[1] - minRange, values[1]]);
}
if (handle === 1 && (values[1] - values[0]) < minRange) {
slider.noUiSlider.set([values[0], values[0] + minRange]);
}
});
}
}))
</script>
@endscript
93 changes: 93 additions & 0 deletions src/Http/Livewire/LfDualRangeFilter.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
<?php

namespace Reach\StatamicLivewireFilters\Http\Livewire;

use Livewire\Attributes\On;
use Livewire\Attributes\Validate;
use Livewire\Component;

class LfDualRangeFilter extends Component
{
use Traits\IsLivewireFilter;

public $view = 'lf-dual-range';

public $selectedMin;

public $selectedMax;

#[Validate('required')]
public $min;

#[Validate('required')]
public $max;

public $step = 1;

public $minRange = 1;

public $format = 'number';

public function mount($defaultMin = null, $defaultMax = null)
{
$this->condition = 'dual-range';
$this->selectedMin = $defaultMin ?? $this->min;
$this->selectedMax = $defaultMax ?? $this->max;
}

public function dispatchEvent()
{
$this->dispatch('filter-updated',
field: $this->field,
condition: $this->condition,
payload: [
'min' => $this->selectedMin,
'max' => $this->selectedMax,
],
command: 'replace',
modifier: $this->modifier,
)
->to(LivewireCollection::class);
}

public function updatedSelectedMin($value)
{
// Ensure min doesn't exceed max - minRange
if ($value > $this->selectedMax - $this->minRange) {
$this->selectedMin = $this->selectedMax - $this->minRange;
}
$this->dispatchEvent();
}

public function updatedSelectedMax($value)
{
// Ensure max doesn't go below min + minRange
if ($value < $this->selectedMin + $this->minRange) {
$this->selectedMax = $this->selectedMin + $this->minRange;
}
$this->dispatchEvent();
}

// #[On('livewire:initialized')]
// public function livewireComponentReady()
// {
// $this->dispatchEvent();
// }

#[On('preset-params')]
public function setPresetSort($params)
{
$paramKey = $this->getParamKey();
if (isset($params[$paramKey]['min'])) {
$this->selectedMin = $params[$paramKey]['min'];
}
if (isset($params[$paramKey]['max'])) {
$this->selectedMax = $params[$paramKey]['max'];
}
}

public function render()
{
return view('statamic-livewire-filters::livewire.filters.'.$this->view);
}
}
5 changes: 5 additions & 0 deletions src/Http/Livewire/LivewireCollection.php
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,11 @@ public function filterUpdated($field, $condition, $payload, $command, $modifier)

return;
}
if ($condition === 'dual-range') {
$this->handleDualRangeCondition($field, $payload, $command, $modifier);

return;
}
$this->handleCondition($field, $condition, $payload, $command);
}

Expand Down
30 changes: 30 additions & 0 deletions src/Http/Livewire/Traits/HandleParams.php
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,36 @@ protected function handleQueryScopeCondition($field, $payload, $command, $modifi
$this->dispatchParamsUpdated();
}

protected function handleDualRangeCondition($field, $payload, $command, $modifier)
{
$minModifier = 'gte';
$maxModifier = 'lte';

// If the modifier is set, we need to extract the min and max modifiers
if ($modifier !== null) {
[$minModifier, $maxModifier] = explode('|', $modifier);
}

$minParamKey = $field.':'.$minModifier;
$maxParamKey = $field.':'.$maxModifier;

switch ($command) {
case 'replace':
$this->params[$minParamKey] = $payload['min'];
$this->params[$maxParamKey] = $payload['max'];
break;

case 'clear':
unset($this->params[$minParamKey]);
unset($this->params[$maxParamKey]);
break;

default:
throw new CommandNotFoundException($command);
}
$this->dispatchParamsUpdated();
}

protected function runCommand($command, $paramKey, $value)
{
switch ($command) {
Expand Down
2 changes: 2 additions & 0 deletions src/ServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
use Livewire\Livewire;
use Reach\StatamicLivewireFilters\Http\Livewire\LfCheckboxFilter;
use Reach\StatamicLivewireFilters\Http\Livewire\LfDateFilter;
use Reach\StatamicLivewireFilters\Http\Livewire\LfDualRangeFilter;
use Reach\StatamicLivewireFilters\Http\Livewire\LfRadioFilter;
use Reach\StatamicLivewireFilters\Http\Livewire\LfRangeFilter;
use Reach\StatamicLivewireFilters\Http\Livewire\LfSelectFilter;
Expand Down Expand Up @@ -46,6 +47,7 @@ public function bootAddon()
Livewire::component('livewire-collection', LivewireCollectionComponent::class);
Livewire::component('lf-checkbox-filter', LfCheckboxFilter::class);
Livewire::component('lf-date-filter', LfDateFilter::class);
Livewire::component('lf-dual-range-filter', LfDualRangeFilter::class);
Livewire::component('lf-radio-filter', LfRadioFilter::class);
Livewire::component('lf-range-filter', LfRangeFilter::class);
Livewire::component('lf-text-filter', LfTextFilter::class);
Expand Down
Loading

0 comments on commit 61f685e

Please sign in to comment.