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

serialize() ignores input elements of type submit #2321

Closed
teo1978 opened this issue May 16, 2015 · 21 comments
Closed

serialize() ignores input elements of type submit #2321

teo1978 opened this issue May 16, 2015 · 21 comments

Comments

@teo1978
Copy link

teo1978 commented May 16, 2015

Expected output:

mensaje_id=2&texto=lalala&comentar=Comentar

Observed output:

mensaje_id=2&texto=lalala

serialize() should serialize the EXACT SAME DATA that would be sent by the browser if the form was sent normally. That includes input elements of type "submit", but jquery ignores them.

I can't believe I'm reporting this bug in 2015.

@dmethvin
Copy link
Member

The documentation says:

Note: Only "successful controls" are serialized to the string. No submit button value is serialized since the form was not submitted using a button. - http://api.jquery.com/serialize/

This is a dup of trac-1138 and before that, trac-3523. The latter was discussed in in 2008. Those are discoverable via Google.

@teo1978
Copy link
Author

teo1978 commented May 16, 2015

No submit button value is serialized since the form was not submitted using a button

Ok, so that's by wrong design.

http://www.w3.org/TR/html401/interact/forms.html#h-17.13.2

A successful control must be defined within a FORM element and must have a control name.
However: [...]

  • If a form contains more than one submit button, only the activated submit button is successful.
  1. By that definition, if the form has only one submit button, it is succesful
  2. It says THE ACTIVATED submit button. It doesn't say anything about "being submitted using a button". If the submit event has been triggered by clicking a given submit button, I can't see any way to not consider that to be "the activated" submit button.

@teo1978
Copy link
Author

teo1978 commented May 16, 2015

From http://bugs.jquery.com/ticket/11138

When you serialize using code no button is pressed

Wrong: it is if a button press triggered the submit event.

and if a button press triggered the code you'll need to add it to the serialized input yourself.

You shouldn't have to.

@dmethvin
Copy link
Member

The documentation says what the method does. The tickets explain the reasoning. There is no submit button activated when you call .serialize() from within jQuery. Besides, it would be unfair to change the behavior now and penalize the people who read the documentation.

@teo1978
Copy link
Author

teo1978 commented May 16, 2015

The documentation says what the method does.

I got it: it is documented. Sorry for missing that. Yet the behavior is wrong.

The tickets explain the reasoning.

which is wrong

There is no submit button activated when you call .serialize() from within jQuery

Unless you call it from a listener that has been triggered by pressing the button.

Besides, it would be unfair to change the behavior now

Backward compatibility is an argument, indeed. It is to be considered whether to fix the behavior and break BC or keep a wrong, inconsistent behavior for the sake of BC. I've seen BC broken in the past in jQuery in favour of improved consistency. Also, it's not that easy to incur in a case where the change would actually do harm, though of course it is possible.

and penalize the people who read the documentation.

Indeed, you could be penalizing people who read the documentation and worked around the incorrect (but documented) behavior. But see above.

@dmethvin
Copy link
Member

Unless you call it from a listener that has been triggered by pressing the button.

How would jQuery know that, as opposed to being called some other way? Can you show some code?

@mr21
Copy link
Contributor

mr21 commented May 17, 2015

@teo1978, omg, there is no reason to be aggressive...

@dmethvin,
Modify the .serialize methode is impossible (because it's not linked with any event) but why not include something in the event of .submit? Maybe it's possible with the new document.activeElement.
Look: http://jsfiddle.net/Mr21/u1uLt3d9/

@teo1978
Copy link
Author

teo1978 commented May 17, 2015

Aggressive? I frankly don't think I'm the one who's been aggressive

@teo1978
Copy link
Author

teo1978 commented May 17, 2015

Modify the .serialize methode is impossible

I may be missing something but couldn't document.activeElement be used inside .seriazize()? Doesn't your example demonstrate that it would work?

@mr21
Copy link
Contributor

mr21 commented May 17, 2015

activeElement is the current DOM element who has actually the focus. So... when jQuery is serializing the form, I suppose we can't have the guaranty the focus is still on the submit button :/

@teo1978
Copy link
Author

teo1978 commented May 17, 2015

If it wasn't, then your example above wouldn't work either, would it?

@mr21
Copy link
Contributor

mr21 commented May 17, 2015

Hmm yep but I use activeElem just after the submit callback. .serialize is not depending of any event or callback, you can call this methode when you want, not only in the submit callback.

@teo1978
Copy link
Author

teo1978 commented May 17, 2015

Of course.
But if you call it from anything else than a submit event, then it's ok that no submit button is included in serialization automatically, because it is not a succesful input element by definition.

The only question is whether using activeElement is reliable and cross-browser. That's worth investigating and this issue should be reopened (also if that turns our not to work for all cases I'm pretty sure there are other ways to be explored, as this issue had always been dismissed as non existing)

Also, according to the definition of successful given in the standard, when there's only one submit button, it should always be included (unless there's some caveat about that), and that seems trivial.

@teo1978
Copy link
Author

teo1978 commented May 17, 2015

The only question is whether using activeElement is reliable

I mean whether three are cases in which the submit button triggering the event triggering serialize may not be the active element for some reason

@scottgonzalez
Copy link
Member

I mean whether three are cases in which the submit button triggering the event triggering serialize may not be the active element for some reason

That's an extremely common occurrence. Forms are frequently submitted via other form controls. See http://jsbin.com/xutubediya/1

@teo1978
Copy link
Author

teo1978 commented May 17, 2015

That's an extremely common occurrence. Forms are frequently submitted via other form controls.

That's not an occurrence of what I'm talking about at all. If you're sending the form via other form controls, then either:
a) there's only one submit button. In this case, according to the definition of "succesful controls" given in the standard, the submit button should be included, and that's trivial to implement in serialize() because you just have to search for submit buttons inside the form and check if there's only one,
OR
b) there are more than one. Then, if you sent the form via another form control, then none of the buttons is "succesful" and hence it's ok that they are not included in serialize.

Actually, there seems to be a discrepancy between the definition of succesful in the standard cited above and browser behavior (at least Chrome). Chrome (when sending the form without any javascript) sends the first submit input element if you send the form by hitting Enter. If that's the correct behavior (in which case the definition in the standard is either unclear or I'm missing something), then again, having serialize() behave the same is trivial, because it's just a matter of finding the first submit element (when none is the activeElement)

@scottgonzalez
Copy link
Member

That's not an occurrence of what I'm talking about at all.

Actually, it is. You said:

But if you call it from anything else than a submit event, then it's ok that no submit button is included in serialization automatically, because it is not a succesful input element by definition.

And since it's impossible to know that we're "inside a submit event", you suggested we use document.activeElement to detect that. Implicit form submission shows that such a check is not a viable solution.

@teo1978
Copy link
Author

teo1978 commented May 17, 2015

And since it's impossible to know that we're "inside a submit event", you suggested we use document.activeElement to detect that. Implicit form submission shows that such a check is not a viable solution.

I meant a submit event triggered by clicking on a submit button.

For implicit submission, see my last comment.

@teo1978
Copy link
Author

teo1978 commented May 17, 2015

For implicit submission, see my last comment.

Mmm, no, sorry, that alone isn't enough to distinguish whether or not we're inside a submit event.

it's impossible to know that we're "inside a submit event"

Aren't you a bit too fast in declaring it's IMPOSSIBLE?
You can detect submit event, right? Isn't it possible for jQuery to store a variable (a reference to the form) when jQuery intercepts a submit event, before all user-defined listeners (added via jQuery) are executed, and then reset that variable to null (or whatever) when jQuery finishes processing the submit event? So, serialize() would be able to check whether or not it's being called from within a submit event? I guess it's not trivial, but... impossible?

@dmethvin
Copy link
Member

The value of document.activeElement is notoriously unreliable, not set consistently in all browsers and it even throws errors in some versions of IE; both jQuery core and jQuery UI have to incorporate workarounds for that. Plus there are cases like detached elements and cross-frame access where the value won't be correct or available.

This is a huge amount of magic to apply just to get a value just for some cases. So instead of having a simple note in the docs saying "we don't add this, add it yourself", we have a big list of conditions where we will fail to do it because of browser issues. I don't see it being worth the inconsistency, especially because people don't read the existing docs and making them more complicated won't help things.

If you're looking for a simple workaround, put a hidden input in the form with the name/value pair you want to send with the submit button, and don't give the submit button a name so it won't be successful if submitted by the user without JavaScript.

@teo1978
Copy link
Author

teo1978 commented May 17, 2015

The value of document.activeElement is notoriously unreliable,

Ok, so what about the other solution?

You can detect submit event, right? Isn't it possible for jQuery to store a variable (a reference to the form) when jQuery intercepts a submit event, before all user-defined listeners (added via jQuery) are executed, and then reset that variable to null (or whatever) when jQuery finishes processing the submit event? So, serialize() would be able to check whether or not it's being called from within a submit event?

.

If you're looking for a simple workaround,

No, I wasn't. I was hoping for a better jQuery where one wouldn't need any workaround at all in order to have a form guaranteed to be serialized always exactly the same way as it would be if sent by the browser.

But I do understand that the lack of that is mostly JavaScript's fault itself, which apparently doesn't provide you a method to obtain that, obliging you (i.e. jQuery) to write from scratch the code that does the serialization, having to mimic what the browser itself would do.

@lock lock bot locked as resolved and limited conversation to collaborators Jun 19, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Development

No branches or pull requests

4 participants