Side navigation
#7601 closed bug (invalid)
Opened November 22, 2010 10:56PM UTC
Closed November 23, 2010 06:18AM UTC
Last modified November 24, 2010 02:06AM UTC
jQuery breaks DOM when setting html() string beginning with a newline
Reported by: | simeyla | Owned by: | simeyla |
---|---|---|---|
Priority: | undecided | Milestone: | 1.5 |
Component: | manipulation | Version: | 1.4.4 |
Keywords: | Cc: | ||
Blocked by: | Blocking: |
Description
I have an AJAX call that returns HTML beginning with a newline. I am using ASP.NET and this is not unusual because of the standard ASMX and ASPX templates.
In Internet Explorer when running the following code:
$("#placeholder").html("\\n<p><form class='payment-form'><input type='text' name='field1' value='111' /><div class='foo' /><input type='text' name='field2' value='222' /></form></p>");
the DOM breaks such that:
$("#placeholder form").serialize()
returns 'field1=111' instead of the expected value 'field1=111&field2=222'.
This is because the FORM tag gets nested incorrectly - as can be seen in the resultant DOM after the call to jQuery.html().
" <P> <FORM id=form1><INPUT name=field1 value=111></P></FORM> <DIV class=foo></DIV><INPUT name=field2 value=222> <P></P>"
I can ONLY duplicate the problem with this exact HTML (FORM nested within P and DIV separating two INPUT fields). Using innerHTML directly doesn't cause this problem - nor do other browsers. Nesting the P tag within the FORM fixes the problem.
Here is a full sample of 4 tests. Only 1 fails (as described above).
<html> <head> <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js"></script> <script> $(function() { // the following two blocks of HTML are identical except the P tag is outside the form in the first case var html1 = "<p><form id='form1'><input type='text' name='field1' value='111' /><div class='foo' /><input type='text' name='field2' value='222' /></form></p>"; var html2 = "<form id='form1'><p><input type='text' name='field1' value='111' /><div class='foo' /><input type='text' name='field2' value='222' /></p></form>"; // <FORM> tag nested within <P> RunTest("<FORM> tag nested within <P> tag", html1); // succeeds in Internet Explorer RunTest("<FORM> tag nested within <P> tag with leading newline", "\\n" + html1); // fails with added new line in Internet Explorer // <P> tag nested within <HTML> RunTest("<P> tag nested within <FORM> tag", html2); // succeeds in Internet Explorer RunTest("<P> tag nested within <FORM> tag with leading newline", "\\n" + html2); // succeeds in Internet Explorer even with \\n }); function RunTest(testName, html) { // run with jQuery $("#placeholder").html(html); var jqueryDOM = $('#placeholder').html(); var jqueryFormSerialize = $("#placeholder form").serialize(); // run with innerHTML $("#placeholder")[0].innerHTML = html; var innerHTMLDOM = $('#placeholder').html(); var innerHTMLFormSerialize = $("#placeholder form").serialize(); var expectedSerializedValue = "field1=111&field2=222"; alert( 'TEST NAME: ' + testName + '\\n\\n' + 'The HTML :\\n"' + html + '"\\n\\n' + 'looks like this in the DOM when assigned with jQuery.html() :\\n"' + jqueryDOM + '"\\n\\n' + 'and looks like this in the DOM when assigned with innerHTML :\\n"' + innerHTMLDOM + '"\\n\\n' + 'We expect the form to serialize with jQuery.serialize() to be "' + expectedSerializedValue + '"\\n\\n' + 'When using jQuery to initially set the DOM the serialized value is :\\n"' + jqueryFormSerialize + '\\n' + 'When using innerHTML to initially set the DOM the serialized value is :\\n"' + innerHTMLFormSerialize + '\\n\\n' + 'jQuery test : ' + (jqueryFormSerialize == expectedSerializedValue ? "SUCCEEDED" : "FAILED") + '\\n' + 'InnerHTML test : ' + (innerHTMLFormSerialize == expectedSerializedValue ? "SUCCEEDED" : "FAILED") ); } </script> </head> <div id="placeholder"> This is #placeholder </p> </html>
Attachments (0)
Change History (8)
Changed November 22, 2010 11:02PM UTC by comment:1
owner: | → simeyla |
---|---|
status: | new → pending |
Changed November 22, 2010 11:12PM UTC by comment:2
_comment0: | Sample code: http://jsfiddle.net/B3EgD/ → 1290468340864970 |
---|---|
status: | pending → new |
Sample code: http://jsfiddle.net/B3EgD/
This link will show SUCCEEDED, FAILED, SUCCEEDED, SUCCEEDED for IE7
This link will show SUCCEEDED, SUCCEEDED, SUCCEEDED, SUCCEEDED for Chrome + FF
Confirmed bug exists on jQuery 0 GIT
Changed November 22, 2010 11:39PM UTC by comment:3
component: | unfiled → manipulation |
---|
So... that was a bit much.
Anyway, I'm not convinced this is a jQuery bug - in fact I think it's just a bad mix of markup. When you remove "<div class='foo' />" it works fine.
Changed November 22, 2010 11:50PM UTC by comment:4
I too think this is result of invalid html.
<p><form>...</form></p>
isn't valid XHTML- the action attribute on the form tag is missing
<div class='foo' />
is invalid- input tags aren't allowed this way directly inside a form without being wrapped in e.g. p, div, ...
If you can provide a test case with valid html which still breaks by adding a \\n
to the start of the html we can look into this issue further.
Changed November 22, 2010 11:51PM UTC by comment:5
status: | new → pending |
---|
Changed November 23, 2010 01:19AM UTC by comment:6
status: | pending → new |
---|
@rwaldron @jitter - thanks so much for the prompt help.
it turns out that <p><form> ... </form></p> is indeed invalid XHTML
i had never realized that <P> can only contain Inline Elements + Text
I'm still still slightly scared about the difference in behavior with a leading newline - especially considering how common it is for AJAX responses to be bad XHTML - but see now what was going on - and that it wasn't arbitrary
thanks again
Changed November 23, 2010 06:18AM UTC by comment:7
resolution: | → invalid |
---|---|
status: | new → closed |
The principal issue here was the self-closing <div>
tag. You can usually get away with invalidly nesting things, but you can never self-close a <div>
.
Changed November 24, 2010 02:06AM UTC by comment:8
actually the problem was nesting <form> within <p>
but only when it contained <input/><div></div><input/>
changing <div> to <div></div> still exhibited the problem
Thanks for taking the time to contribute to the jQuery project! Please provide a reduced jsFiddle test case to help us assess your ticket!
Additionally, test against the jQuery 0 GIT version to ensure the issue still exists. Be Excellent to eachother!