'JavaScript this.form returns unexpected form

I got some enclosing form and two nested forms. the two nested forms are evaluated with ajax on buttonclick and the external form has a submit-button.

Simplified markup:

<form id="form1" action="default.asp">
    //some fields inside a list with unnecessary text
    <input type="text" name="shortdesc"/>
    <form id="deleteform" action="delete.asp">
       //dynamically generated checkboxes
       <input type="checkbox" name="deleter" value="somedocument.txt">somedocument.txt<br>
       <input type="checkbox" name="deleter" value="some_otherdocument.doc">some_otherdocument.doc<br>
       <input type="button" onclick="console.log(this.form); ajaxcall('delete.asp', this.form);" />
    </form>
    <form id="addfileform" action="upload.asp">
        <input type="file" name="file"/>
        <input type="button" onclick="console.log(this.form); ajaxcall('upload.asp', this.form);" />
    </form>
    <input type="button" value="send" onclick="dataValidation(form1),"/>
</form>

When checking a checkbox and "submitting" the form, console logs outer form, but when choosing a file and "submitting" that, the correct form gets logged.

Can someone shed some light on why and /or how to fix this?


For clarification: this is supposed to be some site (not HTML5) where you can submit some text-fields to ask the CEO for some changes. I am now supposed to implement a file-append.

The form is handled and created with asp classic (oh the agony, but well...) and as I am not really keen to keep the whole form-data throughout two redirects(one for the upload and one for the displaying of uploaded files) I had decided to go for AJAX.

FYI: console.log(document.getElementById('deleteform')) returns undefined



Solution 1:[1]

HTML forms cannot be nested. What happens here is the browser sees your first <form id="form1"> tag, but it ignores the nested <form id="deleteform"> tag.

Then it sees the </form> and closes the <form id="form1">. After that it sees the <form id="addfileform"> tag and starts a new form, which gets closed by the next </form>.

Then there is the last <input type="submit" value="send"> button, which is parsed as expected but is not inside any form at all.

Finally there is an extra </form> at the end which it ignores.

In other words, it's the same as if you'd written:

<form id="form1" action="default.asp">
    <input type="checkbox" name="deleter" value="somedocument.txt">somedocument.txt<br>
    <input type="checkbox" name="deleter" value="some_otherdocument.doc">some_otherdocument.doc<br>
    <input type="button" onclick="console.log(this.form); ajaxcall('delete.asp', this.form);" />
 </form>
<form id="addfileform" action="upload.asp">
    <input type="file" name="file"/>
    <input type="button" onclick="console.log(this.form); ajaxcall('upload.asp', this.form);" />
</form>
<input type="button" value="send" onclick="dataValidation(form1),"/>

One easy way to see when something like this happens is to use the DOM inspector in your browser. This shows the DOM that the browser generated from your HTML code - which will sometimes surprise you! You should also validate your HTML code as others have mentioned.

When you try console.log(document.getElementById('deleteform')), that logs undefined because as described above, your deleteform never made it into the DOM.

Solution 2:[2]

You can have multiple forms in a single HTML provided they are pointing to different actions. Nesting of form tags is prohibited

Please go through this W3 specification

http://www.w3.org/TR/xhtml1/#prohibitions

Solution 3:[3]

Generally speaking, you should not use nested forms. If, for any reason, you have the need to use nested forms, perhaps, you should consider changing the architecture of your web-application.

For instance, in your above example, you can replace nested forms with fieldsets, and directly control their respective submit buttons via click event, getting just the necessary info for your ajax calls.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2
Solution 3 Eternal1