htmx
htmx copied to clipboard
Inserting a form inside a table row doesn't work - should it?
`I want to add a form to the last row of a table to allow an easy way to add new data.
<form hx-post="/add-station" hx-target="#pywrr-main">
<tr>
<td><input type="text" name="station_id" id="station_id" required></td>
<td><input type="text" name="station_name" id="station_name" required></td>
<td><input type="text" name="station_url" id="station_url" required></td>
<td></td>
<td>
<button type="submit" value="submit">Add</button>
</td>
<td></td>
</tr>
</form>`
When I use HTMX to add this and inspect the page, the code looks like this, the form is closed immediately and no longer works, because the fields are outside of the form.
<form hx-post="/add-station" hx-target="#pywrr-main"></form>
<tr>
<td><input type="text" name="station_id" id="station_id" required></td>
<td><input type="text" name="station_name" id="station_name" required></td>
<td><input type="text" name="station_url" id="station_url" required></td>
<td></td>
<td>
<button type="submit" value="submit">Add</button>
</td>
<td></td>
</tr>
Should this work?
Shouldn't your form be inside your tr, and not the other way around? As stated in the tr element's documentation
| Permitted parents | <table> (only if the table has no child <tbody> element, and even then only after any <caption>, <colgroup>, and <thead> elements); otherwise, the parent must be <thead>, <tbody> or <tfoot> |
|---|
So I suppose your form is getting closed because when meeting the tr, the parser requires its parent to be one of the mentioned above You should probably try to put your form inside the tr instead?
A "workaround" could be to include the specific elements in the submit. A hx-include of the parent element could work. Like "closest tr".
https://htmx.org/attributes/hx-include/
Thanks for the comments.
I also tried putting the form inside the tr tag -
<tr>
<form hx-post="/add-station" hx-target="#pywrr-main">
<td><input type="text" name="station_id" id="station_id" required></td>
<td><input type="text" name="station_name" id="station_name" required></td>
<td><input type="text" name="station_url" id="station_url" required></td>
<td></td>
<td>
<button type="submit" value="submit">Add</button>
</td>
<td></td>
</form>
</tr>
The behaviour is the same (=form tag is closed immediately), so that doesn't work for me either. I have not tried the hx-include work around, I'll give this a shot and post the results here in 1-2 days-
Oh, you're right, I should've tested what I suggested before posting 😅 It's actually the same issue there ; as stated in the td element's documentation
| Permitted parents | A <tr> element. |
|---|
So you cannot have a tr > form > td hierarchy. It is a common HTML problem. Btw just to clarify, if you were to write this HTML in a blank page, even without htmx, the same thing would happen (so it's not related to htmx directly).
If you want to keep the behaviour of a form, with the required attributes, the default behaviour of hitting the Enter key to submit, what you could do instead is wrap your entire table in your form
Something like
<form hx-post="/add-station" hx-target="#pywrr-main">
<table>
<thead>
<tr>
<th>ID</th>
<th>Name</th>
<th>URL</th>
</tr>
</thead>
<tbody>
<tr>
<td><input type="text" name="station_id" id="station_id" required></td>
<td><input type="text" name="station_name" id="station_name" required></td>
<td><input type="text" name="station_url" id="station_url" required></td>
<td><button type="submit" value="submit">Add</button></td>
</tr>
</tbody>
</table>
</form>
You can play it on this JSFiddle I've just added the htmx demo script and a template element in there, to make it work and generate some visible result
He probably aims to have a context per row. So he may add hx-include to each tr, I think. It is inherited.
Just a quick comment: The form inside a TR row worked in Chrome when I was using the whole body as a target and only stopped working when I started to use htmx to push the table inside a div inside the body.
But you're right, it may be illegal HTML, that's why I hesitated to call it a bug.
Thanks for the comments. In my table, the other rows have buttons like "delete" so I didn't want those to be inside the form. I'll test hx-include when I'm on a proper computer and will report success or failure in a few days.
the initial design from OP (
<form></form>
<table>
...
<tr><td><button /></td></tr>
</table>
)
should actually work with a small change:
<form id="myform"></form>
<table>
...
<tr id="mytr"><td><button form="myform" /></td></tr>
</table>
as per spec (#mytr not necessary for spec, but is for following..)
~~However.. this doesn't seem to work with htmx :( specifically, the <form> with hx-trigger="change from:#mytr" doesn't pick up change events as i expect.~~
EDIT: i take it back, this works fine, i stuffed up testing.