bigskysoftware/htmx

A nested hx-get works incorrectly

cardinal-II opened this issue · 6 comments

For the following html code, I expect that the outer div GETs the back-end every 5s (this works) and the button changes its caption immediately after clicking (this doesn't work).

The div contains a button that can GET the back-end for a new button caption. Load polling works for the div but clicking the button doesn't change the button's caption immediately. The button disappears and appears only after 5s with a new caption. The GET request of the button fires immediately but the button caption doesn't change at once.

<div id="div"
  hx-trigger="load delay:5000ms"
  hx-get="/next_stroke"
  hx-select="#div"
  hx-target="#div"
  hx-swap="outerHTML">

    <button 
        id="button"
        hx-get="/change_button_caption"
        hx-target="#button"
        hx-swap="outerHTML"
        >{{@caption}}
    </button>

</div>

some hx properties are inherited down to sub tags and in this case the hx-select is doing this and changing the button's swap behavior possibly causing your issues. setting a different hx-select on the button may resolve your issue.

setting a different hx-select on the button may resolve your issue.

Yes, that works. Thanks.
Here's the working code:

<div id="div"
  hx-trigger="load delay:5000ms"
  hx-get="/next_stroke"
  hx-select="#div"
  hx-target="#div"
  hx-swap="outerHTML">

    <button 
        id="button"
        hx-get="/change_button_caption"
        hx-select="#button" <------------- This is the select.
        hx-target="#button"
        hx-swap="outerHTML"
        >{{@caption}}
    </button>

</div>

But there is the same problem if I add a table and a few buttons in it:

<div id="div"
  hx-trigger="load delay:5000ms"
  hx-get="/next_stroke"
  hx-select="#div"
  hx-target="#div"
  hx-swap="outerHTML">

    <button 
        id="button"
        hx-get="/change_button_caption"
        hx-select="#button"
        hx-target="#button"
        hx-swap="outerHTML"
        >{{@caption}}
    </button>
    
    <table>

        <thead>
            ...
        </thead>
        <tbody>
            <tr>
                <td>
                    <button 
                        id="pick_button_11"
                        hx-post="/pick/11"
                        hx-select="tbody"
                        hx-target="tbody"
                        hx-swap="innerHTML"
                        >Pick
                    </button>
                </td>
            </tr>
            <tr>
                <td>
                    <button 
                        id="pick_button_12"
                        hx-post="/pick/12"
                        hx-select="tbody"
                        hx-target="tbody"
                        hx-swap="innerHTML"
                        >Pick
                    </button>
                </td>
            </tr>
        </tbody>
    </table>

</div>

Try putting an id on the tbody tag and target and selecting this id like you did in your previous working example

Putting an id on the tbody tag doesn't work.

Seems you are using innerHTML for your table buttons while you were using outerHTML with your previous examples.

  • Could it be that you'd want a hx-select="tr" instead?
  • Or swap the outerHTML of your tbody instead of its innerHTML?
  • Could you otherwise make sure that your server correctly sends a tbody in the response and not only tr (in which case the hx-select selector wouldn't find any match with the above code)?

Hope this helps!