Skip to main content

Bug Tracker

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 rwaldron comment:1

owner: → simeyla
status: newpending

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!

Changed November 22, 2010 11:12PM UTC by simeyla comment:2

_comment0: Sample code: http://jsfiddle.net/B3EgD/1290468340864970
status: pendingnew

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 rwaldron comment:3

component: unfiledmanipulation

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.

http://jsfiddle.net/rwaldron/xYtTq/1/

Changed November 22, 2010 11:50PM UTC by jitter 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 jitter comment:5

status: newpending

Changed November 23, 2010 01:19AM UTC by simeyla comment:6

status: pendingnew

@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 snover comment:7

resolution: → invalid
status: newclosed

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 anonymous 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