1

I'm showing a toast alert, controlling visibility with alpinejs, and want the alert to dim after a couple of seconds and be hidden after some more seconds unless the mouse hovers over it.
I got the dimming working, but don't know how to interrupt the timeout that hides the element.

<div
  x-data="{visible: true, dimmed: false}"
  x-show="visible"
  x-effect="setTimeout(() => dimmed = true, 5000);setTimeout(() => visible = false, 10000)"
  x-on:mouseover="dimmed = false"  // <-- How can I stop the second setTimeout() here?
  x-transition.duration.500ms
  :class="dimmed ? 'opacity-60' : 'opacity-100'"
  class="flex alert alert-info justify-between">
    <div>Some message here</div>
    <div x-on:click="visible = false">
      <button class="btn btn-sm btn-square btn-info">
        Close
      </button>
    </div>
</div>

In js I would declare a variable for the setTimeout() and then call cancelTimeout() on that variable but I don't know how to do this using alpine.

Additionally want to restart the setTimeout() once the mouse leaves the <div>. I guess this could easily be done by defining another setTimeout in x-data and then calling that @onmouseleave, but I can't figure out how to interrupt the timeout in the first place.

1 Answer 1

2

Do something like this, add a mouse over and mouse leave event that can start/stop the timer. Mouse over can call a function to stop the timer and mouse leave can do the inverse.

<div
  x-data="toast()"
  x-show="visible"
  x-transition.duration.500ms
  :class="dimmed ? 'opacity-60' : 'opacity-100'"
  class="flex alert alert-info justify-between"
  x-init="startTimers()"
  x-on:mouseover="cancelTimers(); dimmed = false"
  x-on:mouseleave="startTimers()"
>
  <div>Some message here</div>
  <div x-on:click="visible = false">
    <button class="btn btn-sm btn-square btn-info">
      Close
    </button>
  </div>
</div>

<script> part:

function toast() {
  return {
    visible: true,
    dimmed: false,
    dimTimeout: null,
    hideTimeout: null,
    startTimers() {
      this.cancelTimers();
      this.dimTimeout  = setTimeout(() => this.dimmed = true  , 5000);
      this.hideTimeout = setTimeout(() => this.visible = false, 10000);
    },
    cancelTimers() {
      clearTimeout(this.dimTimeout);
      clearTimeout(this.hideTimeout);
    }
  }
}
Sign up to request clarification or add additional context in comments.

1 Comment

Learned a lot from this example on how to hook into alpinejs. The docs are good but sometimes it really helps to have non-succinct examples.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.