Bug Tracker

Opened 10 years ago

Closed 6 years ago

Last modified 4 years ago

#1414 closed bug (wontfix)

.submit() can fail if something has id="submit"

Reported by: john Owned by: john
Priority: undecided Milestone: 1.5
Component: event Version: 1.4.4rc
Keywords: expando attr Cc:
Blocked by: Blocking:

Description

If an element with an ID of submit exists in a form, .submit() can fail. It's important that this function (in particular) work correctly.

Attachments (2)

jquery_test.html (777 bytes) - added by davidserduke 9 years ago.
test case
1414.html (833 bytes) - added by nathanhammond 9 years ago.
Test Case

Download all attachments as: .zip

Change History (28)

comment:1 Changed 9 years ago by davidserduke

need: PatchTest Case

Can you please submit a test case showing when submit fails?

Changed 9 years ago by davidserduke

Attachment: jquery_test.html added

test case

comment:2 Changed 9 years ago by davidserduke

Milestone: 1.1.41.2.2
need: Test CasePatch
Summary: .submit() can fail in IE.submit() can fail if something has id="submit"

This doesn't appears to be limited to IE. I was able to reproduce the bug in IE, FF, Opera, and Safari. Basically it looks like the jQuery.event.trigger() function checks to see if elem[type] is a function where elem is the <form> and type == "submit".

Unfortunately, when there is an element with an id of "submit" it returns that element instead of the function. It basically shadows the function. At this point, I'm not even sure how to get TO the function.

One thing I did notice is:

when f.submit is a function

f.hasOwnProperty("submit") == false

when f.submit is an element

f.hasOwnProperty("submit") == true

So we could, in theory, do a special case test to see if it is the "wrong" submit and do something else in that case. Unfortunately, as I already mentioned, the submit function is hidden. Perhaps this would work?

$("<form/>").get(0).submit.call(elem);

Not very pretty though. And further testing shows it fails in IE because submit.call is undefined.

Any other thoughts on a possible fix?

comment:3 Changed 9 years ago by joern

These lines are used to reach the action and method attributes of a form in IE:

else if ( value == undefined && jQuery.browser.msie && jQuery.nodeName( elem, "form" ) && (name == "action" || name == "method") )
			return elem.getAttributeNode( name ).nodeValue;

That may work for submit, too.

comment:4 Changed 9 years ago by joern

Of course that won't work in any other browser then IE. And even there is doesn't seem to work. Forget it then...

comment:5 Changed 9 years ago by flesler

Milestone: 1.2.21.2.4

Also, submit is not an attribute, so that function won't work.

comment:6 Changed 9 years ago by nathanhammon

I'd say this is a problem with the HTML spec, not jQuery. What is happening is exactly equivalent to this:

<form action="" method="get">
	<input name="submit" id="submit" type="text />
	<a href="#" onclick="this.parentNode.submit(); return false;"></a>
</form>

With the way forms work for accessing descendant inputs, the child element "submit" is essentially hiding the "submit" method. This is a problem with any attempt to submit a form with JavaScript, not with our implementation. I think we should just leave this one to education: thou shalt not name/id a form element "submit" or "reset" because they hide methods.

In terms of a workaround, we could try adding an <input type="text" /> set focus, and insert a return...

comment:7 Changed 9 years ago by flesler

Resolution: duplicate
Status: newclosed

This is an old ticket (1.1.3). The compromised is now wrapped with a try/catch so this shouldn't cause any exception. Reopen if you still experience a problem.

comment:8 Changed 9 years ago by john

Milestone: 1.2.41.3
Resolution: duplicate
Status: closedreopened
Version: 1.1.31.2.6

Well, it doesn't throw an exception, correct - but it needs to actually work. Right now we just kind of fall on our side if no event is provided to us. One option is to create a temporary form and utilize its .submit property to force a submission (haven't tested this, may not work).

comment:9 Changed 9 years ago by nathanhammon

Then if we must, I think the easiest way to trigger submit will be to do something like this:

$('<input type="submit" style="display: none;"/>').appendTo('form').trigger('click');

I don't know how that would affect other event handlers being fired (I know that catching the submit event isn't always easy), but it seems to work in the simple test case I created.

Changed 9 years ago by nathanhammond

Attachment: 1414.html added

Test Case

comment:10 Changed 9 years ago by john

I proposed a solution to Ariel over IM - to add some code to our event triggering code that looks something like this:

document.createElement( elem.nodeName )[ method ].call( elem );

I haven't tested it yet to see if it actually works - but it's worth a shot.

comment:11 Changed 6 years ago by snover

#6264 is a duplicate of this ticket.

comment:12 Changed 6 years ago by snover

Keywords: expando attr added
Milestone: 1.31.5
Priority: majorblocker
Status: reopenedopen
Version: 1.2.61.4.4rc

This is one of those things that should probably get resolved along with the attr rewrite which also targets addressing the DOM expando crap.

comment:13 Changed 6 years ago by danheberden

#7699 is a duplicate of this ticket.

comment:14 Changed 6 years ago by anonymous

Solution to this would be to call the method from the prototype chain.

HTMLFormElement.prototype.submit.call(elem);

comment:15 Changed 6 years ago by 3point2

i just ran into this and spent 3 hours trying to figure out why submit() wasn't working on my form. turned out the form had an input element with name="submit". when i renamed it to something else, submit() worked again. would be great to see this fixed soon.

comment:16 Changed 6 years ago by yc

@anonymous-14 it turns out that that solution is not IE<7 compatible. Check out Matt's solution here: http://stackoverflow.com/q/4465028/172322 ; It seems to work fairly well, and doesn't seem to present any cross-browser issues.

comment:17 Changed 6 years ago by Rick Waldron

Priority: blockerundecided
Resolution: wontfix
Status: openclosed

After a lot of research and attempts to patch this over the last 2 days and ultimately over the last three years, I think its safe to say its a "needsdocs" situation.

What have we learned? DO NOT USE "submit" or "reset" as input name attribute values.

Epic work, documented here: https://github.com/gnarf37/jquery/commits/bug_1414

comment:18 Changed 6 years ago by Rick Waldron

Last edited 6 years ago by Rick Waldron (previous) (diff)

comment:20 in reply to:  17 Changed 6 years ago by gnarf@…

Replying to rwaldron:

After a lot of research and attempts to patch this over the last 2 days and ultimately over the last three years, I think its safe to say its a "needsdocs" situation.

Already doced on .submit()

Forms and their child elements should not use input names or ids that conflict with properties of a form, such as submit, length, or method. Name conflicts can cause confusing failures. For a complete list of rules and to check your markup for these problems, see DOMLint.

comment:21 Changed 6 years ago by Rick Waldron

#8330 is a duplicate of this ticket.

comment:22 Changed 6 years ago by Rick Waldron

#8544 is a duplicate of this ticket.

comment:23 Changed 5 years ago by Rick Waldron

#10839 is a duplicate of this ticket.

comment:24 Changed 5 years ago by dmethvin

#10909 is a duplicate of this ticket.

comment:25 Changed 4 years ago by anonymous

This is a problem that can cause hours of headaches for developers. Understand that it seems to tough to fix. But as noted here, this is a "needsdocs" situation and the documentation for .submit() should definitely be updated accordingly at http://api.jquery.com/submit/

comment:26 Changed 4 years ago by dmethvin

There are dozens of properties that can cause this. It's not just submit. If you want to go through the list here and propose a reasonable set of changes to a series of pages it would be welcome.

http://kangax.github.com/domlint/

The pull request should be submitted to http://github.com/jquery/api.jquery.com/

Note: See TracTickets for help on using tickets.