Tabernero
Tabernero

Reputation: 635

The form tag dissapears when is parsed to div's inner HTML

I have a selfmade web backend where the user can load some XML files with partial HTML code and replace it with the content of the webpage, which works almost fine.

One of the functions parse the read XML to a temporary hidden div to work on it with innerHTML, the problem is that the form tag dissappears in this proccess.

This is the "critical part":

var DocContent; // This var will have the HTML code (the XML document content) withount modifications
// ...
document.getElementById("TempDiv").innerHTML = DocContent; // This is the part where the code is parsed.

When I told the page to show me the code it returns these:

DocContent:

<p>
    <span lang='en'>This form</span>
</p>
<form action='./contact.php' method='POST'>
    <label for='Name'>
        <span lang='en'>Full Name</span>
    </label>
    <input id='Name' type='text' name='Name' maxlength='50' required>
    <hr>
    <button id='Submitter' type='submit'>
        <span lang='en'>Send</span>
    </button>
</form>
<p>
    <span lang='en'>blah blah</span>
</p>

and TempDiv's innerHTML:

<p>
    <span lang='en'>This form</span>
</p>

    <label for='Name'>
        <span lang='en'>Full Name</span>
    </label>
    <input id='Name' type='text' name='Name' maxlength='50' required>
    <hr>
    <button id='Submitter' type='submit'>
        <span lang='en'>Send</span>
    </button>

<p>
    <span lang='en'>blah blah</span>
</p>

The <form></form> tags completely dissappeared, and the rest of the elements are recognized as children of the form's parent.

Upvotes: 0

Views: 157

Answers (2)

Peter B
Peter B

Reputation: 24147

The reason is most likely that your TempDiv is already embedded in a <form>, and then the inner <form> is discarded because forms cannot be nested.

This snippet will show the difference if you Run it. TempDiv1 is inside a <form>, TempDiv2 is not:

var DocContent =
  "<p>\r\n" +
  "    <span lang='en'>This form</span>\r\n" +
  "</p>\r\n" +
  "<form action='./contact.php' method='POST'>\r\n" +
  "    <label for='Name'>\r\n" +
  "        <span lang='en'>Full Name</span>\r\n" +
  "    </label>\r\n" +
  "    <input id='Name' type='text' name='Name' maxlength='50' required>\r\n" +
  "    <hr>\r\n" +
  "    <button id='Submitter' type='submit'>\r\n" +
  "        <span lang='en'>Send</span>\r\n" +
  "    </button>\r\n" +
  "</form>\r\n" +
  "<p>\r\n" +
  "    <span lang='en'>blah blah</span>\r\n" +
  "</p>";

document.getElementById("TempDiv1").innerHTML = DocContent;
document.getElementById("TempDiv2").innerHTML = DocContent;
console.log("TempDiv1.innerHTML = " + document.getElementById("TempDiv1").innerHTML);
console.log("TempDiv2.innerHTML = " + document.getElementById("TempDiv2").innerHTML);
<div style="float:left; background:#eef">
  <form>
    <div id="TempDiv1"></div>
  </form>
</div>

<div style="float:left; background:#fee">
  <div id="TempDiv2"></div>
</div>

Upvotes: 1

iska
iska

Reputation: 2248

This could happen for a number of reasons. The usual suspect would be a stray <form> tag before the <div id="TempDiv">, or maybe around it. Check out this fiddle to understand what I mean.

This happens due to the fact, that HTML-parsers correct malformed HTML. During parsing the parser maintains a list of open elements, or unclosed tags, and decides on each new element what to do. As you know nested <form>s are not allowed and this triggers something called the adoption agency algorithm during the parsing phase, which decides what elements get reparented so that the DOM tree stays valid.

var content = "\
<p><span lang='en'>This form</span></p>\
<form action='./contact.php' method='POST'>\
    <label for='Name'>\
        <span lang='en'>Full Name</span>\
    </label>\
    <input id='Name' type='text' name='Name' maxlength='50' required>\
    <hr>\
    <button id='Submitter' type='submit'>\
        <span lang='en'>Send</span>\
    </button>\
</form>\
<p><span lang='en'>blah blah</span></p>"

document.getElementById("temp").innerHTML = content;
<form>
<div id="temp"> </div>

Upvotes: 1

Related Questions