Skip to content

Commit

Permalink
feat: live mode for datepicker range mode (#653)
Browse files Browse the repository at this point in the history
* feat: live mode for datepicker range mode

Using `wire:model.live` makes datepicker with mode set to `range` behave
unexpectedly as described in #649. This is due to livewire sending
update as long as the user selects the first date. I can't find anyway
to customize the behavior of livewire's `.live` modefier. My proposed
fix for instances when you want live update as long as the user selects
a range is to add a `live` attribute to datepicker. This will add a
change event listener using `x-on:change` which checks if the date is
complete by spliting it with `'to'` and checking if the resulting array
contains two items. The listener only gets attached if the mode is set
to range, hence making the live attribute range mode exclusive.

* feat: remove live attribute

This makes the `wire:model.live` work seemlessly if the `mode` is set
`range`. This implementation checks if `mode` is set to `range` and the
`wire:model.live` attribute is present, then it rewrites the attribute
but setting it back to `wire:model` and adding a new attribute called
`live` which is used to check weather or not to attach the `x-on:change`
listener since we will removed the `wire:model.live` in the setup
function.

* WIP

---------

Co-authored-by: Robson Tenório <rrtenorio@gmail.com>
  • Loading branch information
itsmenewbie03 and robsontenorio authored Oct 2, 2024
1 parent 5b77a8e commit a04203e
Showing 1 changed file with 11 additions and 0 deletions.
11 changes: 11 additions & 0 deletions src/View/Components/DatePicker.php
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,14 @@ public function errorFieldName(): ?string

public function setup(): string
{
// Handle `wire:model.live` for `range` dates
if (isset($this->config["mode"]) && $this->config["mode"] == "range" && $this->attributes->wire('model')->hasModifier('live')) {
$this->attributes->setAttributes([
'wire:model' => $this->modelName(),
'live' => true
]);
}

$config = json_encode(array_merge([
'dateFormat' => 'Y-m-d H:i',
'altInput' => true,
Expand Down Expand Up @@ -85,6 +93,9 @@ public function render(): View|Closure|string
<div
x-data="{instance: undefined}"
x-init="instance = flatpickr($refs.input, {{ $setup() }});"
@if(isset($config["mode"]) && $config["mode"] == "range" && $attributes->get('live'))
@change="const value = $event.target.value; if(value.split('to').length == 2) { $wire.set('{{ $modelName() }}', value) };"
@endif
x-on:livewire:navigating.window="instance.destroy();"
>
<input
Expand Down

0 comments on commit a04203e

Please sign in to comment.