Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ensure that events are always sent on blur, but this time correctly #3097

Merged

Conversation

SteffenDE
Copy link
Collaborator

Relates to: #3033
Relates to: #2318
Fixes: #3076

The old "fix" from #3033 had a fatal flaw because it would call an old callback on blur.

This new commit adjusts the behavior to properly use the correct callback by hooking into the cycle logic and ignoring the throttle in case of blur, leaving the rest of the logic nearly untouched. This requires us to clear the throttle timeout though, because otherwise we would call the callback again after a blur, or multiple times when new events happen after blur but before the next throttle timeout triggers.

The debounce/throttle code is not that easy to understand, but this time I'm more confident that the solution is actually correct. (famous last words)

Relates to: phoenixframework#3033
Relates to: phoenixframework#2318
Fixes: phoenixframework#3076

The old "fix" from phoenixframework#3033 had a fatal flaw because it would call an old
callback on blur.

This new commit adjusts the behavior to properly use the correct callback
by hooking into the cycle logic and ignoring the throttle in case of blur,
leaving the rest of the logic nearly untouched. This requires us to clear
the throttle timeout though, because otherwise we would call the callback
again after a blur, or multiple times when new events happen after blur
but before the next throttle timeout triggers.

The debounce/throttle code is not that easy to understand, but this time
I'm more confident that the solution is actually correct.
(famous last words)
@SteffenDE SteffenDE marked this pull request as draft February 7, 2024 19:54
When throttling events, the last event was discarded, but this is not
what I would expect from a throttled event. Throttling an input should
ensure that it is only emitted at most every `delay` milliseconds, but
it should always emit the last event after the delay has passed. This
change ensures that the last event is always emitted when throttling.

This of course means that events that are emitted shortly after the last
throttled event will still be emmitted immeditately, basically starting
a new throttle window.
@SteffenDE
Copy link
Collaborator Author

So, I actually added another change that ensures that the last event is always emitted, even when throttling. Currently we discard the event when the throttle timeout expires which causes weird behavior when using inputs like a slider, because the slider position does not reflect the value on the server as the last event is never emitted. When blurring the input after the last throttle expired we also would not send the event, because the trigger function was already reset. Let me know if this makes sense.

@SteffenDE SteffenDE marked this pull request as ready for review February 7, 2024 20:15
@chrismccord chrismccord merged commit 8cffda7 into phoenixframework:main Feb 8, 2024
5 checks passed
@chrismccord
Copy link
Member

❤️❤️❤️🐥🔥

SteffenDE added a commit to SteffenDE/phoenix_live_view that referenced this pull request Feb 9, 2024
Relates to: phoenixframework#3097

So, in phoenixframework#3097 I changed the throttle behavior to also dispatch an event
after the throttle time has passed to make sure that the last event is
dispatched. However, this caused the event to be dispatched twice in the
case that there was only one event in the first place.

This fixes that, although the throttle code is still a bit of a mess and
should probably be refactored completely at some point.
SteffenDE added a commit to SteffenDE/phoenix_live_view that referenced this pull request Feb 10, 2024
Relates to: phoenixframework#3097
Relates to: phoenixframework#3033
Relates to: phoenixframework#2318
Relates to: phoenixframework#3076

This reverts the changes made in phoenixframework#3097 and phoenixframework#3033. It adds one small
change to the original behavior to clear the throttle timeout on blur.

For cases where the user wants to get the latest value on blur when
throttle is used, adding a `phx-blur={JS.dispatch("change")}` is the
way to go:

```
<input
  name="tick_frequency"
  type="range"
  min="100"
  max="1000"
  value={@tick_frequency}
  phx-throttle="2000"
  phx-change="change-tick-frequency"
  phx-blur={JS.dispatch("change")}
/>
```
SteffenDE added a commit to SteffenDE/phoenix_live_view that referenced this pull request Feb 10, 2024
Relates to: phoenixframework#3097
Relates to: phoenixframework#3033
Relates to: phoenixframework#2318
Relates to: phoenixframework#3076

This reverts the changes made in phoenixframework#3097 and phoenixframework#3033. It adds one small
change to the original behavior to clear the throttle timeout on blur.

For cases where the user wants to get the latest value on blur when
throttle is used, adding a `phx-blur={JS.dispatch("change")}` is the
way to go:

```
<input
  name="tick_frequency"
  type="range"
  min="100"
  max="1000"
  value={@tick_frequency}
  phx-throttle="2000"
  phx-change="change-tick-frequency"
  phx-blur={JS.dispatch("change")}
/>
```
SteffenDE added a commit to SteffenDE/phoenix_live_view that referenced this pull request Feb 10, 2024
Relates to: phoenixframework#3097
Relates to: phoenixframework#3033
Relates to: phoenixframework#2318
Relates to: phoenixframework#3076

This reverts the changes made in phoenixframework#3097 and phoenixframework#3033. It adds one small
change to the original behavior to clear the throttle timeout on blur.

For cases where the user wants to get the latest value on blur when
throttle is used, adding a `phx-blur={JS.dispatch("change")}` is the
way to go:

```
<input
  name="tick_frequency"
  type="range"
  min="100"
  max="1000"
  value={@tick_frequency}
  phx-throttle="2000"
  phx-change="change-tick-frequency"
  phx-blur={JS.dispatch("change")}
/>
```
SteffenDE added a commit to SteffenDE/phoenix_live_view that referenced this pull request Feb 10, 2024
Relates to: phoenixframework#3097
Relates to: phoenixframework#3033
Relates to: phoenixframework#2318
Relates to: phoenixframework#3076

This reverts the changes made in phoenixframework#3097 and phoenixframework#3033. It adds one small
change to the original behavior to clear the throttle timeout on blur.

For cases where the user wants to get the latest value on blur when
throttle is used, adding a `phx-blur={JS.dispatch("change")}` is the
way to go:

```
<input
  name="tick_frequency"
  type="range"
  min="100"
  max="1000"
  value={@tick_frequency}
  phx-throttle="2000"
  phx-change="change-tick-frequency"
  phx-blur={JS.dispatch("change")}
/>
```
chrismccord pushed a commit that referenced this pull request Feb 14, 2024
Relates to: #3097
Relates to: #3033
Relates to: #2318
Relates to: #3076

This reverts the changes made in #3097 and #3033. It adds one small
change to the original behavior to clear the throttle timeout on blur.

For cases where the user wants to get the latest value on blur when
throttle is used, adding a `phx-blur={JS.dispatch("change")}` is the
way to go:

```
<input
  name="tick_frequency"
  type="range"
  min="100"
  max="1000"
  value={@tick_frequency}
  phx-throttle="2000"
  phx-change="change-tick-frequency"
  phx-blur={JS.dispatch("change")}
/>
```
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
2 participants