HTMX hide text and show loading spinner while request in progress
Asked Answered
A

3

5

I'm using HTMX and I have a button inside a form that says 'Send' and when the form is submitted a loading spinner appears next to it. I want the 'Send' to disappear and only the loading spinner to be shown while the request is in progress. How can I do that?

<form hx-post="/test">
      <button type="submit">
        <span>Send</span>
        <svg class="htmx-indicator ml-2 animate-spin h-5 w-5" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
          <circle class="opacity-25" cx="12" cy="12" r="10" stroke="black" fill="transparent" stroke-width="4"></circle>
          <path class="opacity-75" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path>
        </svg>
      </button>
    </div>
  </form>
Arvonio answered 26/10, 2022 at 17:33 Comment(0)
C
5

Here is an example of my button that shows a loading spinner and hides the text when HTMX is making the request.

<button class="flex items-center relative rounded-md bg-slate-50 px-3.5 py-2.5 text-sm font-semibold text-slate-950 shadow-sm" 
    hx-get="/my-route" 
    hx-trigger="click, keyup[code=='Space'] from:body" 
    hx-target="#myContainer" 
    hx-swap="outerHTML swap:0.25s" 
    hx-indicator="#spinner" 
    type="button">
    <svg class="spinner animate-spin" id="spinner" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 12a9 9 0 1 1-6.219-8.56"></path></svg>
    <span class="button-text">Click me</span>
</button>

Then, my css

.spinner {
  display: none;
}

.htmx-request .spinner {
  display: inline;
}

.htmx-request.spinner {
  display: inline;
}

.htmx-request.spinner ~ .button-text {
  display: none;
}

Basically, I use the css ~ selector to find the adjacent button text and hide it while the .htmx-request class is added to the actual indicator.

Culex answered 24/1 at 18:43 Comment(0)
O
4

The .htmx-request class should be added to the button that triggered the request, so you can use that with some CSS to hide the text.

https://htmx.org/docs/#request-operations

Obala answered 27/10, 2022 at 14:44 Comment(0)
H
0

You can achieve this with a few tweaks to your html and some css.

<form hx-post="/test" hx-indicator="#loader">
        <style>
            .htmx-indicator {
                display: none
            }

            .htmx-indicator.htmx-request {
                display: inline;
            }

            .htmx-indicator.htmx-request~span {
                display: none;
            }
        </style>
        <button type="submit">
            <svg id="loader" class="htmx-indicator ml-2 animate-spin h-5 w-5" xmlns="http://www.w3.org/2000/svg"
                fill="none" viewBox="0 0 24 24">
                <!-- loader truncated for brevity -->
            </svg>
            <span>Send</span>
        </button>
        </div>
    </form>
  1. Have htmx add an "htmx-request" class to the spinner when ajax requests are in flight. See https://htmx.org/attributes/hx-indicator/

  2. Re-arrange the "send" label and "svg" so that you can easily target the svg as next sibling with css.

Note that I used display: none which will completely remove the nodes from the DOM. If you'd rather make it invisible but retain its position in the DOM, you can simply opacity instead.

Helenehelenka answered 7/6 at 20:2 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.