-1

I have been searching the web for hours for this but I couldn't find an explanation or solution. So let's see if anyone can provide me with one here...

The problem I am having is that I have some "invalid" old HTML and we are currently revamping the website by injecting some other div's etc through JQuery. But after having changed the DOM some functionalities are not working anymore.

Let me give you an example. The old HTML is something like:

<table>
   <form method="POST">
   <tr>
      <td><input type="text" value="test" /></td>
   </tr>
   <tr>
      <td><input type="submit" value="SEND!" /></td>
   </tr>
   </form>
</table>

As you can see there is a <form> nested outside of a <tr> which is actually not valid. But it is interpreted correctly by the browser and it's working. BUT if I manipulate the DOM through JQuery the browser (Firefox in my case) notices it's wrong and the button is not working anymore. Checking my Firebug would give something like:

<table>
   <form method="POST"></form>
   <tr>
      <td>...

So obviously the submit button is not working anymore since it has "automatically" closed the <form> tag and the submit is not embedded anymore.

Can anyone shine some light on this issue? Why is this happening and what can I do to prevent this from happening (apart from changing the original HTML).

Thanks a lot !!

EDIT:

To avoid getting just the answer of "invalid markup" let me show you a second example.

<input type="text" id="something" value="" />

Javascript function that is loading on onLoad:

function setRequired() {
   document.getElementById('something').setAttribute('aria-required', 'true');
}

After the onload I can check this in Firebug and it works as expected:

<input type="text" id="something" value="" aria-required="true" />

But if I add the DOM manipulation after that it ends up in:

<inputaria-required="true" type="text" value="" id="something"></inputaria-required="true">

EDIT2:

As for the DOM modification, I am just wrapping the entire body of the page inside a structure of <div> tags. So something like (simplified):

$('body').wrapInner('<div class="container">');

To see this issue in action check this page (make sure you view it in Firefox because it works in IE).

Manuel Allenspach
  • 12,467
  • 14
  • 54
  • 76
Jules
  • 7,148
  • 6
  • 26
  • 50
  • 3
    "Why is this happening" Because it's invalid markup? I'm not sure what else you want us to say. – BoltClock Jan 10 '13 at 10:48
  • I realize that, but this is an old website which is impossible to redo from scratch. The invalid markup is interpreted correctly by the browser at first though. Why does it change its mind after the DOM manipulation? – Jules Jan 10 '13 at 10:52
  • It's simple, just move the form tag outside the table. Doesn't require rebuilding anything from scratch. – sevenseacat Jan 10 '13 at 10:54
  • @sevenseacat Yes but that is just one example which I noticed. I added a second one now and there might still be more undetected ones. I rather find the root cause rather than treating the disease. On top of that we're talking about a few hundreds of pages. – Jules Jan 10 '13 at 11:03
  • @BoltClock Added a second example which is not invalid markup. – Jules Jan 10 '13 at 11:03
  • I can't reproduce your second example. I thought it was impossible to generate invalid HTML with JavaScript DOM methods... Can you post a full HTML document that shows the issue? – Álvaro González Jan 10 '13 at 11:06
  • So what does the DOM manipulation look like? It wouldn't normally affect elements that you don't change, so are you doing something like reparsing the entire page after appending code to it? – Guffa Jan 10 '13 at 11:07
  • @Guffa I am just wrapping the entire body into a structure of `
    ` tags (I edited my question to give you a simplified example).
    – Jules Jan 10 '13 at 12:19
  • @ÁlvaroG.Vicario Please have a look at http://www.icannotchoose.com/testingWrap.html in Firefox. I reproduced the issue there. – Jules Jan 10 '13 at 12:40

3 Answers3

1

This is being done by the browser not jQuery. The only way you can stop it is to make your HTML code valid, ie. put the <table> inside the <form>

Rory McCrossan
  • 331,213
  • 40
  • 305
  • 339
  • I'm not saying it's JQuery, but it's the DOM modification that is triggering this. My question is why? The browser interpreted the invalid markup correctly before. – Jules Jan 10 '13 at 10:53
  • 1
    `The browser interpreted the invalid markup correctly before.` If it did then you were just lucky, as it really shouldn't have. The only solution is to amend your HTML. – Rory McCrossan Jan 10 '13 at 10:54
0

That is an invalid markup. I suggest you either correct your markup or use Jquery .submit() for this if changing of markup is not possible.

kapillohakare
  • 840
  • 6
  • 7
0

The code you've added later is quite a mess. I'd say it requires a very precise timing to work properly:

// Bind a page load event handler
$(document).ready(function() {
    LoadStyle();
});

// Manipulate page with raw HTML 1/2 seconds after page load
function LoadStyle() {
    setTimeout(function () {
    var outerbody = "<div>";
    var outerbodyEnd = "<\/div>";
    var frameHtml = $('body').html();
        var frameHtml = $('body').html();
        document.body.innerHTML = outerbody + frameHtml + outerbodyEnd;
    }, 500);
}

// Override previous onload handlers
window.onload = setRequired;

// Manipulate page with DOM methods right after page load
function setRequired() {
    var field;
    field = document.getElementsByName('required_one')[0];
    setAttrNS(field, "aria-required", "true");
}

Whatever, if you increment the setTimeout() delay to 5000 milliseconds, you'll see the invalid node is generated by LoadStyle(). Upon further investigation, I've composed this shorter snippet that still exhibits the issue (no jQuery involved):

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
    <head>
        <title>Test wrapping the content</title>
        <script type="text/javascript" language="javascript">
            window.onload = function(){
                var field = document.getElementsByName('required_one')[0];
                field.setAttributeNS("http://www.w3.org/2005/07/aaa", "aria-required", true);
                alert(document.getElementsByTagName("body")[0].innerHTML);
            };
        </script>
    </head>
    <body>
        <input type="text" name="required_one" value="This should show">
    </body>
</html>

The invalid HTML is generated by .innerHTML. Neither Firebug's HTML panel nor the alert() display a namespaced attribute. Sadly, I'm not familiar with namespaces so I can't tell you what's wrong: your code, Firebug or Firefox.

Álvaro González
  • 142,137
  • 41
  • 261
  • 360
  • Agreed. The timeout might not be needed. The `LoadStyle()` function was done by an offshore company stating it was needed in some versions of IE. Didn't see the problem myself so I don't know why it's there. As for the `setAttributeNS` it's coming from the W3C WAI: http://www.w3.org/WAI/PA/WCAG20/WD-WCAG20-TECHS-20070910/ARIA4.html . So either this is a JavaScript bug with the `.setAttributeNS` function (am I the first one to find this?) or indeed with Firefox. – Jules Jan 10 '13 at 14:02
  • Namespaces aside, the `.innerHTML` issue must be Firefox bug. Chrome and Opera don't exhibit such behaviour. – Álvaro González Jan 11 '13 at 09:19
  • Yes it is only happening in Firefox. Also when using JQuery's functions as `html()`, `wrap()`, ... So JQuery didn't fix the issue either (or they haven't spotted it). – Jules Jan 14 '13 at 12:11