Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

buttons outside of forms with form=attribute get their values stuck #1749

Closed
jwhitaker-swiftnav opened this issue Aug 30, 2023 · 9 comments
Closed

Comments

@jwhitaker-swiftnav
Copy link

jwhitaker-swiftnav commented Aug 30, 2023

Reproduction:

<form id="externalForm" hx-post="/test" hx-trigger="input from:#idText">
  <input id="idText" type="text" name="t1" value="textValue">
</form>
<button id="submit" form="externalForm" type="submit" name="b1" value="buttonValue">button</button>

Click #submit :

  • post receives {"b1":"buttonValue","t1":"textValue"} (correct)

Now change #idText (note we have swapped anything, form is the same element):

  • post receives {"b1":"buttonValue", "t1":"changed"} (incorrect, "b1" should not be there)

I've tried to set up a test case for this in #1748 but I'm possibly stupid and my test breaks for reasons I can't understand.

I've also tried a partial fix in the same issue, which works for my reproduction, but breaks for other tests.

Related to #1559 but maybe not introduced there.

EDIT: this seems to only happen on firefox :(

@Telroshan
Copy link
Collaborator

Hey, I tried to reproduce the issue in this JSFiddle, though I don't get the same payload
Click #submit:
image
Now change #idText
image

The button's value is correctly not included there, am I missing something?

Also, please note I had to add the submit event in your form's hx-trigger, otherwise the button would trigger a standard form submit, out of htmx's scope

@jwhitaker-swiftnav
Copy link
Author

that explains the issue i was having with a test reproduction, thanks I'll test further.

@jwhitaker-swiftnav
Copy link
Author

jwhitaker-swiftnav commented Aug 30, 2023

Thanks heaps for your call on submit, i've fixed the test case in the pr to work and reproduce this properly.

N.B. your jsfiddle reproduces the issue for me, note you have to click the submit button and THEN change the input field?
EDIT: ahh, seems this is only reproducible on Firefox.. I was also running my test case manually in firefox.
EDIT2: now I can't reproduce on your jsfiddle again, I think I'm going nuts? Maybe I'll go to sleep and come back to this tomorrow.

@Telroshan
Copy link
Collaborator

Oh right, I'm testing on Chrome
Gave it a shot on Firefox, works the same for me
Yeah I'm clicking the button then modifying the input

From the top of my head I can't think what's causing that thing for you 😅

Let me know after that sleep session if it still happens 😆

@jwhitaker-swiftnav
Copy link
Author

got it! reproducing is more specific than I thought. codesandbox: https://codesandbox.io/p/sandbox/htmx-express-demo-forked-xn6zhp?welcome=true

<!-- initial page -->
<form
  hx-get="/xhr"
  hx-trigger="input from:#t1, submit"
  hx-target="#target"
  hx-swap="outerHTML"
  style="display: flex; flex-direction: column;"
  >
  <input id="t1" name="t1" value="textValue" autocomplete="off" />
  <button name="b1" value="buttonValue1">Button 1</button>
  <div id="target">
    <button name="b2" value="buttonValue2">Button 2</button>
  </div>
</form>
<!-- response from /xhr -->
<div id="target">
  <pre>${JSON.stringify(req.query)}</pre>
  <button id="b2" name="b2" value="buttonValue2">Button 2</button>
</div>

To reproduce:

  1. click Button 2.
    a. result: {"t1":"textValue","b2":"buttonValue2"} (expected, all good)
  2. immediately focus the input field
  3. type in the input field
    a. result: {"t1":"text","b2":"buttonValue2"} (bug!)

Requirements to reproduce:

  • only happens on Firefox
  • button2 seems to need to be swapped in by htmx
  • button2 cannot have an id attr to observe this bug
  • if the text field is focused, then unfocused, then focused again, then the bug disappears

Given the above I'm not surprised i thought i was going nuts!

@Telroshan
Copy link
Collaborator

Lmao that's so specific 😭
Sincere congratulations on finding the exact reproduction steps
The fact that it only happens on Firefox on top of that makes me nervous
I'll try to investigate when I get the chance!

@Enterprise-Gods
Copy link

Using the link provided to codesandbox and using Firefox on my side all is working fine. Using Firefox 117.0 (64-bit). Open "https://xn6zhp-3000.csb.app/" into local Firefox instance.

clicked Button 2.
a. result: {"t1":"textValue","b2":"buttonValue2"} (expected, all good)
immediately focus the input field
started typing type in the input field by entering "Second Test"
a. result: {"t1":"Second Test","b2":"buttonValue2"} ALL GOOD !!!!
(I was also APPENDING text to original value "textValue" and all was good also. :)
Appended "MyNewTest" to existing "textValue" and got "{"t1":"textValueMyNewTest","b2":"buttonValue2"}"

In don't see an issue with your demo code and HTMX also.

@jwhitaker-swiftnav
Copy link
Author

Using the link provided to codesandbox and using Firefox on my side all is working fine. Using Firefox 117.0 (64-bit). Open "https://xn6zhp-3000.csb.app/" into local Firefox instance.

clicked Button 2. a. result: {"t1":"textValue","b2":"buttonValue2"} (expected, all good) immediately focus the input field started typing type in the input field by entering "Second Test" a. result: {"t1":"Second Test","b2":"buttonValue2"} ALL GOOD !!!! (I was also APPENDING text to original value "textValue" and all was good also. :) Appended "MyNewTest" to existing "textValue" and got "{"t1":"textValueMyNewTest","b2":"buttonValue2"}"

In don't see an issue with your demo code and HTMX also.

You have reproduced the bug. The expected value on entering text is just {t1:...}. b2 should not be there, because the button was not pressed.

@Telroshan
Copy link
Collaborator

Following up late on this @jwhitaker-swiftnav
I'm investigating the issue
I found out that the underlying problem is that :

  • htmx uses an internal data to keep track of the last clicked button in a form
  • it relies on the focusout event to clear that reference
  • on Chrome, the focusout event gets called when the element is swapped and removed from the DOM
  • however on Firefox for some reason, the event isn't fired at all, so the reference is never cleared, the internal state still has a reference to the removed button as the last clicked button, thus its values gets included, until you click out to focusout the form

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants