You Cannot Submit Non-Rendered Forms

Posted April 18, 2008 at 8:39 AM by Ben Nadel

Tags: Javascript / DHTML

The other night, at Rob Gonda's NYCFUG presentation, we were talking about jQuery and AJAX and I wondered if a non-rendered Form element could be submitted. By that, I mean a Form node that existed in memory but was not actually part of the rendered page's document object model (DOM). See this demo if you are not sure what I mean:

  • <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  • <html>
  • <head>
  • <title>Non-Rendered Form Submission</title>
  •  
  • <script type="text/javascript" src="jquery-1.2.3.pack.js"></script>
  • <script type="text/javascript">
  •  
  • function SubmitForm(){
  • var jForm = $(
  • "<form action='test.cfm' method='post'>" +
  • "<input type='hidden' name='test' value='Cool!'>" +
  • "</form>"
  • );
  •  
  • // Submit the form.
  • jForm.submit();
  • }
  •  
  • </script>
  • </head>
  • <body>
  •  
  • <h1>
  • Non-Rendered Form Submission
  • </h1>
  •  
  • <form>
  •  
  • <input
  • type="button"
  • value="Submit Non-Rendered Form"
  • onclick="SubmitForm()"
  • />
  •  
  • </form>
  •  
  • </body>
  • </html>

As you can see above, when you click on the button, the SubmitForm() method is triggered. This method then creates an in-memory Form node with nested input value using jQuery and tries to submit it. On the server, I have the form submitting to this page to see if it worked:

  • <!--- Param the form variable. --->
  • <cfparam name="FORM.test" type="string" default="{NULL}" />
  •  
  • <!---
  • Add the form value to the log file so that we can
  • see what the form file is actually submitting.
  • --->
  • <cffile
  • action="append"
  • file="#ExpandPath( './debug.txt' )#"
  • output="#FORM.test#"
  • addnewline="true"
  • />

Well, the long and short story is that it didn't work. I tried it in FireFox as well as Internet Explorer 7. Nothing. Oh well, just a quick experiment.



Reader Comments

Apr 18, 2008 at 8:42 AM // reply »
11,243 Comments

Also, FYI, if you put this line in right before the submit:

$( "body" ).append( jForm );

The form does get attached to the body and the submission does work (but forwards the user's page to the test.cfm).


Apr 18, 2008 at 10:08 AM // reply »
79 Comments

Isn't $("whatever") short for document.getElementById("whatever")?

If so, you're trying to get an id="<form ...", which doesn't exist, of course.

I kind of like the idea behind it though - you could create a form quickly and then submit it. I'm not sure why I'd use it, but the possibility of doing so is rather exciting.

I also think using the term "in memory form" with the explanation "I mean a Form node that existed in memory" is confusing. I had no idea what you meant until I saw the example. =)


Apr 18, 2008 at 10:11 AM // reply »
11,243 Comments

@Sammy,

The $() constructor in jQuery can be a CSS and ID selector (as you have demonstrated); however, if presented with what it sees as HTML then it will create those nodes on the fly and return them in a jQuery object. This is why the example works IF You first append the jForm object to the BODY tag.

I thought it would be cool to be maybe be able to upload files using this kind of hidden form post.


Apr 18, 2008 at 10:40 AM // reply »
79 Comments

Ben,

Thanks for the clarification. Gotta love the single responsibility principle. =)


Apr 18, 2008 at 10:42 AM // reply »
11,243 Comments

Gotta love jQuery :) I guess you could call that "$" a factory method?


Apr 18, 2008 at 11:42 AM // reply »
5 Comments

I actually don't see the problem. Can you present me with an example of when you can't add the form to the DOM?


Apr 18, 2008 at 11:45 AM // reply »
11,243 Comments

@nitro2k01,

I am not worries about submitting a form once the FORM is attached to the DOM, that is standard. I wanted to see if you could submit a form that was not part of the DOM and therefore, not interacting with the page directly or forwarding the user to the action page.


Apr 18, 2008 at 11:50 AM // reply »
5 Comments

Exactly. Even if it's an interesting experiment I don't see a good reason not to interact with the DOM. (Especially not when the form is to be submitted, so that the DOM is destroyed anyway)


Apr 18, 2008 at 12:24 PM // reply »
6 Comments

Ben, I don't really see a need to submit a form that we never rendered, but just like you mentioned in the first comment, once you append the form to the body it works in every browser.

The case where I usually need that is when I add entire forms with an Ajax call and need the user to be able to submit them, and it works...


Apr 18, 2008 at 12:27 PM // reply »
11,243 Comments

@Rob,

It was just an experiment :) I am not sure it would ever be useful. However, after you said in the presentation that files could not be uploaded via AJAX, I thought maybe if an non-rendered form could be submitted, you could possibly submit files this way, behind the scenes.


Apr 18, 2008 at 1:21 PM // reply »
132 Comments

@Ben

The common design pattern for doing file uploads without blocking user interaction with the page is to use a form that's action targets a hidden iframe, or use a form inside a hidden iframe and call it's submit().


Apr 18, 2008 at 1:31 PM // reply »
11,243 Comments

@Elliott,

Yeah, I think that is the way to go.


Apr 18, 2008 at 2:58 PM // reply »
10 Comments

Why use a form like that at all anyways? With JQuery you can simply send an HTTP request (e.g. POST) directly to the server. You can do this various ways, including the serialization of an existing form, or using JSON to represent the data structure.

It's one of those things that's good to know, I suppose.


Apr 18, 2008 at 3:04 PM // reply »
11,243 Comments

@Shayne,

In his presentation, Rob was saying that you could not send file data since AJAX style submits can only sent textual data. I figured, if you could submit a non-rendered form, you could also submit a non-rendered file input box. It was just a thought....


Apr 18, 2008 at 4:32 PM // reply »
10 Comments

@Ben

Hrm ... I can't say I've personally achieved this, that is to upload file data over AJAX, but I am curious as to why it wouldn't be possible - it seems as if a company I know of does exactly that with their accounting software they've developed.

If I concede to that possibility it might not be possible - I'd presume you could accomplish this "asynchronous file upload" by using a hidden IFRAME and using it as the target for the FORM. Google Maps was initially based off this pseudo-asynchronous "AJAX like" approach. In fact our warehouse management system uses this method too and works like a charm.


Apr 18, 2008 at 6:32 PM // reply »
11,243 Comments

@Shayne,

Yes, I believe all that you can do.


Apr 18, 2008 at 7:53 PM // reply »
29 Comments

@Ben,

You commented this morning: "I guess you could call that "$" a factory method?" In fact, the jQuery documentation refers to $() as a factory method.

And since it returns an instance of the jQuery class and doesn't require the "new" operator, I see no reason to disagree!


Apr 18, 2008 at 8:49 PM // reply »
5 Comments

On my way home this night, I came to think of a perfectly good reason why you can't post non-rendered forms. Before a form is added to the DOM the engine has no clue which document it belongs to. Is this a problem? When there are multiple frames or windows, it is a problem since the newly created form could be added anywhere in the DOM tree. Even if the object was created a in one frame it could theoretically be added to another frame or or newly opened window.
From that point of view I think it's correct that an orphan form can't be submitted.


Jan 24, 2010 at 4:22 AM // reply »
1 Comments

The simplest way to post a form without changing the URL of the viewing page is to create an iframe that is positioned out of view and setting the target of the form to it and then submitting it.


Jan 24, 2010 at 10:13 PM // reply »
11,243 Comments

@Justin,

This is true, especially when you need to upload a File - something that cannot be done with AJAX technology exclusively.



Post A Comment

Comment Etiquette: Please do not post spam. Please keep the comments on-topic. Please do not post unrelated questions or large chunks of code. And, above all, please be nice to each other - we're trying to have a good conversation here.

Please review the following issues:

Author Name:


Author Email:

Author Website:

Comment:

Supported HTML tags for formatting: <strong>bold</strong>   <em>italic</em>   <code>code</code>







  • Help Wanted - Find Your Next ColdFusion Job
Ben Nadel's Company - Epicenter Consulting Recent Blog Comments
May 23, 2013 at 5:19 AM
Ask Ben: Print Part Of A Web Page With jQuery
How to print also the background color of table cells and table lines ... read »
May 23, 2013 at 3:55 AM
Javascript Array Methods: Unshift(), Shift(), Push(), And Pop()
very interesting and helpful too. ... read »
May 22, 2013 at 5:35 PM
Script Tags, jQuery, And Html(), Text() And Contents()
This is still an issue 2 years later. jQuery is supposed to remediate these cross browser issues, no? I have been unable to find any statement from the jQuery team calling this behavior "by de ... read »
May 22, 2013 at 12:44 PM
Ask Ben: Query Loop Inside CFScript Tags
In cf10, if you call a function that has: local.result = {}; local.result.msg = ""; local.svc = new query(); local.svc.setSQL("SELECT * FROM..."); local.obj = local.svc.exe ... read »
May 22, 2013 at 12:29 PM
Strange Interaction Between DeserializeJson(), ArrayContains(), And Database Values In ColdFusion
@Ben: What version of Java are you using? Also, did you test users.id to see what Java reports as the data type? I wonder if it's not a Java primitive data type, but getting returned as something ... read »
May 22, 2013 at 11:47 AM
Strange Interaction Between DeserializeJson(), ArrayContains(), And Database Values In ColdFusion
@Dana, Awesome - so it looks like this bug was fixed in ColdFusion 10. Thanks so much for double-checking that. ... read »
May 22, 2013 at 11:37 AM
Strange Interaction Between DeserializeJson(), ArrayContains(), And Database Values In ColdFusion
When I c&p and run on cf10, I get: Selected User IDs: 1,4 User 1 selected: YES - YES User 2 selected: NO - NO User 3 selected: NO - NO User 4 selected: YES - YES User 5 selected: NO - ... read »
May 22, 2013 at 11:27 AM
Strange Interaction Between DeserializeJson(), ArrayContains(), And Database Values In ColdFusion
@Tom, Good thought, but no dice. Both of these still exhibit the same behavior: users.id[ users.currentRow ] users[ "id" ][ users.currentRow ] It's just something whacky happening with ... read »
InVision App - Prototyping Made Beautiful With Prototyping Tools