Closed dmanpearl closed 4 months ago
I have a successful fix implemented with a small code-change in response-targets.js. It processes custom targets on "beforeOnLoad" because "beforeSwap" is being suppressed. I think there is a deeper problem causing the suppression, but I am open to sharing and discussion if anyone is interested and will eventually make a PR.
Here is the temporary fix:
onEvent: function (name, evt) {
// Original v1.9.10: Bug in which 'hx-target-*' fails to swap if 'hx-target' is also set.
// if (name === "htmx:beforeSwap" &&
// DGM 2-27-2024: Add 'hx-target-*' error processing while 'hx-target' is simultaneously defined.
if ((name === "htmx:beforeSwap" || name === "htmx:beforeOnLoad") &&
Resolved: The solution is to move the "hx-ext" attribute
In my case, "hx-target-error" pointed to a div 'id' outside of the div containing "hx-ext".
I came across this undocumented solution here
Example incorrect usage:
<tr>
<td>
<div hx-ext="response-targets">
<button
hx-get={% url "testbed:rebound" %}
hx-headers='{"custom": "{{ test.id }}"}'
hx-target-error="#GET-{{ test.id }}-fail"
hx-target="#GET-{{ test.id }}-ok"
class="btn btn-sm btn-primary testbed-btn"
>
GET {{ test.msg }}
</button>
</div>
</td>
<td>
<span id="GET-{{ test.id }}-ok" />
<span class="text-danger" id="GET-{{ test.id }}-fail" />
</td>
</tr>
Example correct usage:
<tr hx-ext="response-targets">
<td>
<button
hx-get={% url "testbed:rebound" %}
hx-headers='{"custom": "{{ test.id }}"}'
hx-target-error="#GET-{{ test.id }}-fail"
hx-target="#GET-{{ test.id }}-ok"
class="btn btn-sm btn-primary testbed-btn"
>
GET {{ test.msg }}
</button>
</td>
<td>
<span id="GET-{{ test.id }}-ok" />
<span class="text-danger" id="GET-{{ test.id }}-fail" />
</td>
</tr>
We have a sidebar which loads a content pane in two different parts of the DOM and were stumbling over this. Moving the hx-ext="response-targets"
to the <body>
element fixes this but it feels too broad of a change since we only have to do this for the response-targets
extension. Is there any downside in doing that?
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<script src="https://unpkg.com/htmx.org@1.9.12/dist/htmx.js"></script>
<script src="https://unpkg.com/htmx.org@1.9.12/dist/ext/debug.js"></script>
<script src="https://unpkg.com/htmx.org@1.9.12/dist/ext/response-targets.js"></script>
</head>
<body>
<div id="error"></div>
<div id="nav">
<a
href="#"
hx-ext="response-targets"
hx-get="/fail"
hx-target="#content"
hx-target-error="#error"
>fails</a
>
<a
href="#"
hx-ext="response-targets"
hx-get="/ok"
hx-target="#content"
hx-target-error="#error"
>works</a
>
</div>
<div id="content"></div>
</body>
</html>
htmx extension: response-targets
The Problem
"hx-target-error" will not work when "hx-target" is also defined, but works when hx-target-error is the only target.
I need to have both "hx-target-error" and "hx-target".
Environment
htmx 1.9.10, response-targets 1.9.10, python 3.12, django 5.0.1
Example html:
hx-target
I have tried with various other types of targets such as "next td", "next span", etc. All of them produce a valid target value "request.htmx.target" in the endpoint defined in views.py.
hx-target-error
I have also tried alternatives targets such as "hx-target-*", "hx-target-404", etc with no change in results.
I verified that "response-targets" is installed correctly and being used correctly because when "hx-target" is removed from the "button", then "hx-target-error" works.
Error generation in views.ph
Logs
Work-Around
The current work-around is to omit "hx-target". In this case, 200 success response replace the current DOM object and all errors replace to DOM object pointed to by "hx-target-error". This work-around is NOT acceptable because we need targeted success snippet placement.