Uncaught (in promise) Missing Target: #[object HTMLButtonElement] was not found in the current document.
hansaskov1 opened this issue · comments
I want to try out Alpine-ajax, but I can't get it to work. I have installed it by including it in the head of my HTML file. All seems to work until I interact with the page, and I get an error:
Uncaught (in promise) Missing Target: #[object HTMLButtonElement] was not found in the current document.
E https://cdn.jsdelivr.net/npm/@imacrayon/alpine-ajax@0.5.0/dist/cdn.min.js:1
j https://cdn.jsdelivr.net/npm/@imacrayon/alpine-ajax@0.5.0/dist/cdn.min.js:1
j https://cdn.jsdelivr.net/npm/@imacrayon/alpine-ajax@0.5.0/dist/cdn.min.js:1
r https://cdn.jsdelivr.net/npm/@imacrayon/alpine-ajax@0.5.0/dist/cdn.min.js:1
[cdn.min.js:1:8310](https://cdn.jsdelivr.net/npm/@imacrayon/alpine-ajax@0.5.0/dist/cdn.min.js)
r https://cdn.jsdelivr.net/npm/@imacrayon/alpine-ajax@0.5.0/dist/cdn.min.js:1
I tried to reproduce the toggle example but this error has stumped me.
I am using Bun and Elysia for serving my code and i made a repository to reproduce this error:
https://github.com/hansaskov1/alpine-ajax-button
The entire source code is also here.
import { Elysia } from "elysia";
import { html } from "@elysiajs/html";
const Head = ({ children }: { children: undefined | {} }) => (
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
{/* Alpine and Alpine Ajax */}
<script defer src="https://cdn.jsdelivr.net/npm/@imacrayon/alpine-ajax@0.5.0/dist/cdn.min.js"></script>
<script defer src="https://cdn.jsdelivr.net/npm/alpinejs@3.11.1/dist/cdn.min.js"></script>
</head>
<body>
{children}
</body>
</html>
);
const LikeButton = ({ id }: { id: string }) => (
<form id="like" x-init x-target method="post" action={`/comments/${id}/like`}>
<button name="id" value={id}>Like</button>
</form>
)
const UnlikeButton = ({ id }: { id: string }) => (
<form id="like" x-init x-target method="delete" action={`/comments/${id}/like`}>
<button name="id" value={id} x-autofocus>Unlike</button>
</form>
)
const app = new Elysia()
.use(html())
.get("/", () => (
<Head>
<LikeButton id={"1"} />
</Head>
))
.delete("/comments/:id/like", ({ params }) => (
<LikeButton id={params.id} />
))
.post("comments/:id/like", ({ params }) => (
<UnlikeButton id={params.id} />
))
.listen(3000);
console.log(
`🦊 Elysia is running at ${app.server?.hostname}:${app.server?.port}`
);
Here is the rendered html from the browser
<html lang="en" class=" mrcjhi idc0_350">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script defer="" src="https://cdn.jsdelivr.net/npm/@imacrayon/alpine-ajax@0.5.0/dist/cdn.min.js"></script><script defer="" src="https://cdn.jsdelivr.net/npm/alpinejs@3.11.1/dist/cdn.min.js"></script>
</head>
<body>
<form id="like" x-init="" x-target="button" method="post" action="/comments/1/like">
<button name="id" value="1">Like</button>
</form>
</body>
</html>
Could someone please help me understand and resolve this issue?
Hi, so there's something a bit off with that rendered HTML:
<form id="like" x-init="" x-target="button" method="post" action="/comments/1/like">
x-target
can be either empty (x-target
) or x-target="like"
but,x-target="button"
is the cause of the error. The template code you shared appears fine, I'm not sure where the value of button
would be coming from.
I think i copy pasted the html from my browser incorrectly. The x-target is empty and not button. Sorry for the confusion.
Here is the actual html
<html lang="en" class=" dnvyzo idc0_350">
<head><meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script defer="" src="https://cdn.jsdelivr.net/npm/@imacrayon/alpine-ajax@0.5.0/dist/cdn.min.js"></script>
<script defer="" src="https://cdn.jsdelivr.net/npm/alpinejs@3.11.1/dist/cdn.min.js"></script>
</head>
<body>
<form id="like" x-init="" x-target="" method="post" action="/comments/1/like">
<button name="id" value="1">Like</button>
</form>
</body>
</html>
Based on your answer i am assuming x-target="" should be x-target instead for it to target itself. But i'm not sure if a can configre my html render to not parse it like this
Ah, I was able to track down the problem.
It's some browser DOM weirdness and some unsafe programming on my part. Since your submit button is named id
. In JavaScript, document.querySelector('form').id
will actually reference the <button>
element inside the form instead of the id
attribute on the form 😩. I should be using document.querySelector('form').getAttribute('id')
instead to prevent that name conflict.
I'll try to get a patch out really soon, but in the meantime if you change that button name to something like name="comment_id"
you should have things working.
Amazing! You're so fast. Thank you very much.
Quite a hilarious bug. Good thing you found it.
This also explains why removing name="id" and value="1" from my buttons fixed the issue
Thank you for the thorough details!