Is there a way to submit a non-rendered form?
I have specific scenario where I want to submit a dynamic form to the server. As of now I have achieved this by adding form to the body after creating it using jQuery. It works perfectly, but I wonder why I am not able to submit a in memory form without rendering into the DOM.
Following is the code snippet I have tried:
var action_url = "/post-url";
$(`
<form action=${action_url} method="POST">
<input type="text" value="name1" name="name1"/>
<input type="text" value="name2" name="name2"/>
<input type="text" value="name3" name="name3"/>
</form>
`).appendTo('body').submit();
So, why I am not able to do like below:
var action_url = "/post-url";
$(`
<form action=${action_url} method="POST">
<input type="text" value="name1" name="name1"/>
<input type="text" value="name2" name="name2"/>
<input type="text" value="name3" name="name3"/>
</form>
`).submit();
When I run the above code getting following warning message in console:
Form submission canceled because the form is not connected
When we attempt to insert elements into the document, it would create some DOM nodes cached by document fragments before appending to the document. The nodes cached by document fragments CAN register event handlers and also CAN be triggered, but submit()'s algorithm would be a little different.
DOM nodes in document fragment are NOT part of the active document tree structure and according to the HTML standard documentation, if the form is not connected (associated, created or whatever else similar term) to the browsing context(document), the submission process will be canceled.
For further reading:
Form submission algorithm
DocumentFragment
A form should be on the DOM before submission because afterloading page, every element is attached an event so is recognized by the DOM and jquery or javascript can manipulate. but what you are doing (2nd) doesn't even exist in the DOM so the event submit() is not available to it.
Related
Not sure how I did this last time or else I wouldnt asking here but here is what I'm trying to do.
I have the usual basic form with a javascript function that will submit the form. Question is that after the form is submitted, I have an if statement in PHP that echos a that the form has been submitted. Any help would be greatly appreciated.
//PHP
if($_POST['submitDelete']){
echo "welcome, You form has been submitted";
}
//HTML
<form id="form_id" action="" method="POST">
First name: <input type="text" name="fname"><br>
Last name: <input type="text" name="lname"><br><br>
<input type="hidden" name="submitDelete" TYPE="submit">
</form>
<button type="button" onclick="myFunction()">Submit</button>
//JAVASCRIPT
<script>
function myFunction() {
document.getElementById("form_id").submit();
}
</script>
I can't seem to trigger the if statement in PHP. I also tried using the form name in the if statement and that didnt work either.
A form element must be told where to submit its data to when the submit event takes place. This is accomplished by setting the action attribute value for the form. Leaving that attribute empty does not implicitly set the form to post back to the current page. So, if you want to have a single page form/form processor, you need the action to be set to the current page file name:
<form action="currentPageFileName.php" method="post">
Next, there's no reason a single page can't have multiple forms on it. In that case you would need multiple submit buttons, each tied to a specific form. For this reason, you can't just drop a submit button anywhere on the page that you like unless you add the form attribute to the button to tie it back to the form it is supposed to trigger the submit for. Also, if you simply place the submit button within the form element it "belongs" to, you don't have to worry about this.
Also, you have some invalid HTML with:
<input type="hidden" name="submitDelete" TYPE="submit">
An element may not have the same attribute repeated within it (the case that you type the attribute in makes no difference since HTML is not case-sensitive). So, that code would wind up simply creating a submit button.
Lastly, if all you want to do with your submit button is cause its related form to be submitted, there is no need for JavaScript at all. That is what submit buttons do by default.
So, in the end, you can get rid of the JavaScript in your code completely and change your HTML to this:
<form id="form_id" action="currentFileName.php" method="POST">
First name: <input type="text" name="fname"><br>
Last name: <input type="text" name="lname"><br><br>
<input type="hidden" name="submitDelete" value="true">
</form>
<button type="submit" form="form_id">Submit</button>
I'm trying to include static HTML form inside my Angular 2 (beta2) app but it doesn't do anything when I hit the submit button.
Here's the HTML I use:
<form action="upload_path" method="POST">
<input type="text" name="text" />
<button type="submit">Send</button>
</form>
How can I enable my form to work with Angular2?
With
<form ngNoForm ...>
you can prevent Angular from handling the form.
If you want to use the action attribute of HTML form, you need to disable the behavior of the NgForm directive that catches the submit event and prevents it from being propagated. See this line: https://github.com/angular/angular/blob/master/modules/angular2/src/common/forms/directives/ng_form.ts#L81.
To do that simply add the ngNoForm attribute to your form:
<form ngNoForm action="https://www.google.com" target="_blank" method="POST">
<input name="q" value="test">
<button type="submit">Search</button>
</form>
In this case, a new window will be opened for your form submission.
That said, Angular2 tackles SPAs (Single Page Applications) and in most use cases, you need to stay in the same page when submitting a form. For such use cases, you can leverage the submit event with a submit button:
<form [ngFormModel]="companyForm" (submit)="onSubmit()">
Name: <input [ngFormControl]="companyForm.controls.name"
[(ngModel)]="company.name"/>
<button type="submit">Submit</button>
</form>
Hope it helps you,
Thierry
Angular 2 adds an event handler to forms submit event and blocks the forms form being sent. This is done for the sake of normal AJAX use case where you don't actually want to submit the form (and thus reload the page), but instead catch it on JavaScript and send an AJAX request (or handle the data other ways).
You can bypass this by using your custom event handler which will be called first and in which you send the form already before it goes to the Angular's handler.
To do this, you need to add onsubmit="this.submit()" on your form element like this:
<form action="upload_path" method="POST" onsubmit="this.submit()">
Recently, I am reviewing client side code written by another programmer. I am surprised with code which is used for getting form object.
HTML for Login Form
<form id="frm_login" action="">
<input type="text" name="username" id="username">
<input type="password" name="pwd" id="pwd">
</form>
He has used following code to get form object
$frm = $("input[type='password']").closest("form");
But there is simple code for getting form object which I prefer:
$frm = $("#frm_login");
Is there any reason to use closest to get form object in above scenario?
I would really like to know if there is any performance issues.
The id of element is supposed to be unique. If there is single form on page then there is no need to relate it to its parent using closest. It would have more sense if the form does not have id. Getting form through id seem more straight forward and fast.
If there are multiple forms and one have to get the form in which the element exists then using closest make sense. This could be understood with the following example.
Live Demo
Html
<form id="frm_login1" action="">
<input type="text" name="username" id="username1" />
<input type="password" name="pwd" id="pwd1">
<table>
<tr>
<td>
<input type="text" class="myInputClass" />
</td>
</tr>
</table>
</form>
<form id="frm_login2" action="">
<input type="text" name="username" id="username2">
<input type="password" name="pwd" id="pwd2">
<table>
<tr>
<td>
<input type="text" class="myInputClass" />
</td>
</tr>
</table>
</form>
Javascript
$("input[type='password']").closest("form").each(function(){
alert($(this).find('.myInputClass').val());
});
If there is single form on page then there is no need to relate it to its parent using closest. It would have more sense if the form does not have id. Getting form through id seem more straight forward and fast.
But The Closest() method is very cool and very useful, especially when you start to deal with event delegation in which events are trapped at a higher level in the node tree than are the elements that triggered the event.
the closest() method searches through these elements and their ancestors in the DOM tree and constructs a new jQuery object from the matching elements.
as others said, if you have id, no need to use closest to get parent form. and using id is faster.
HOWEVER, in some cases you need to use closest to get form, for example, if you write a universal function for validating every password input in every form, in this case you don't like to get forms by ids and search for its childes passwordfields to prevent auto submitting, so i guess the guy who wrote the code, is doing this(a function which validates passwords before submit)
$("input[type='password']").each(function(){
$frm = .closest("form");
$frm.submit(function(event){
if( not valid password){
......
return false;
}
});
});
I am writing a very simple web app with three text inputs. The inputs are used to generate a result, but all the work is done in Javascript, so there is no need to submit a form. I'm trying to find a way to get the browser to store input values for autocomplete as it would if they were in a form that was submitted.
I have tried giving the inputs autocomplete="on" manually, but without a form to submit, the browser has no way of knowing when it should store the values, so this has no effect.
I have also tried wrapping the inputs in a form that has onSubmit="return false;", but preventing the form from actually submitting appears to also prevent the browser from storing its inputs' values.
It is of course possible to manually use localStorage or a cookie to persist inputs and then generate autocomplete hints from those, but I'm hoping to find a solution that taps into native browser behavior instead of duplicating it by hand.
Tested with Chrome, IE and Firefox:
<iframe id="remember" name="remember" class="hidden" src="/content/blank"></iframe>
<form target="remember" method="post" action="/content/blank">
<fieldset>
<label for="username">Username</label>
<input type="text" name="username" id="username" value="">
<label for="password">Password</label>
<input type="password" name="password" id="password" value="">
</fieldset>
<button type="submit" class="hidden"></button>
</form>
In your Javascript trigger the submit, e.g. $("form").submit(); $("#submit_button").click() (updated from comments)
You need to return an empty page at /content/blank for get & post (about:blank didn't work for me but YMMV).
We know that the browser saves its information only when the form is submitted, which means that we can't cancel it with return false or e.preventDefault()
What we can do is make it submit the data to nowhere without reloading a page. We can do that with an iframe
<iframe name="💾" style="display:none" src="about:blank"></iframe>
<form target="💾" action="about:blank">
<input name="user">
<input name="password" type="password">
<input value="Login" type="submit">
</form>
Demo on JSfiddle (tested in IE9, Firefox, Chrome)
Pros over the currently accepted answer:
shorter code;
no jQuery;
no server-side page loaded;
no additional javascript;
no additional classes necessary.
There is no additional javascript. You normally attach an handler to the submit event of the form to send the XHR and don't cancel it.
Javascript example
// for modern browsers with window.fetch
document.forms[0].addEventListener('submit', function (event) {
fetch('login.php', {
method: 'post',
body: new FormData(event.target))
}).then(r => r.text()).then(() => { /* login completed */ })
// no return false!!
});
No-javascript support
Ideally, you should let the form work without javascript too, so remove the target and set the action to a page that will receive your form data.
<form action="login.php">
And then simply add it via javascript when you add the submit event:
formElement.target = '💾';
formElement.action = 'about:blank';
I haven't tested this, but it might work if you submit the form to a hidden iframe (so that the form is actually submitted but the current page is not reloaded).
<iframe name="my_iframe" src="about:blank"></iframe>
<form target="my_iframe" action="about:blank" method="get">...</form>
---WITHOUT IFRAME---
Instead of using iframe, you can use action="javascript:void(0)", this way it doesn't go to another page and autocomplete will store the values.
<form action="javascript:void(0)">
<input type="text" name="firstName" />
<button type="submit">Submit</button>
</form>
Maybe you can use this Twitter Typeahead...is a very complete implementation of a autocomplete, with local and remote prefetch, and this make use of localStorage to persist results and also it show a hint in the input element...the code is easy to understand and if you don't want to use the complete jquery plugin, I think you can take a look of the code to see how to achieve what you want...
You can use jQuery to persist autocomplete data in the localstorage when focusout and when focusin it autocompletes to the value persisted.
i.e.
$(function(){
$('#txtElement').on('focusout',function(){
$(this).data('fldName',$(this).val());
}
$('#txtElement').on('focusin',function(){
$(this).val($(this).data('fldName'));
}
}
You can also bind persistence logic on other events also depending on the your application requirement.
For those who would rather not change their existing form functionality, you can use a second form to receive copies of all the form values and then submit to a blank page before your main form submits. Here is a fully testable HTML document using JQuery Mobile demonstrating the solution.
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title></title>
<link rel="stylesheet" href="https://code.jquery.com/mobile/1.4.5/jquery.mobile.structure-1.4.5.min.css" />
<script src="https://code.jquery.com/jquery-1.10.2.min.js"></script>
<script src="https://code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.min.js"></script>
</head>
<body>
<form method="post">
<input type="text" name="email" />
<input type="submit" value="GO" onclick="save_autofill(this);" />
</form>
<script>
function save_autofill(o) {
$(':input[name]', $('#hidden_form')).val(function () {
return $(':input[name=' + this.name + ']', $(o.form)).val();
});
$('#hidden_form').find("input[type=submit]").click();
}
</script>
<iframe name="hidden_iframe" style="display:none"></iframe>
<form target="hidden_iframe" id="hidden_form" action="about:blank" style="display:none">
<input type="text" name="email" />
<input type="submit" />
</form>
</body>
</html>
The save_autofill function just needs to be called on your main form submit button. If you have a scripted function that submits your form, place that call after the save_autofill call. You must have a named textbox in your hidden_form for each one in your main form.
If your site uses SSL, then you must change the URL for about:blank with https://about:blank.
From what i searched.. it seems you need to identify the names. Some standard names like 'name', 'email', 'phone', 'address' are automatically saved in most browser.
Well, the problem is, browsers handle these names differenetly. For example, here is chrome's regex:
first name: "first.*name|initials|fname|first$"
email: "e.?mail"
address (line 1): "address.*line|address1|addr1|street"
zipcode: "zip|postal|post.*code|pcode|^1z$"
But chrome also uses autocomplete, so you can customize the name and put an autocomplete type, but i believe this is not for custom fields..
Here is chrome's standard
And it's another thing in IE, Opera, and Mozilla. For now, you can try the iframe solution there, so you can submit it. (Maybe it's something semi-standard)
Well, that's all i can help.
Make sure you're submitting the form via POST. If you're submitting via ajax, do <form autocomplete="on" method="post">, omitting the action attribute.
you can use "." in both iframe src and form action.
<iframe id="remember" name="remember" style="display:none;" src="."></iframe>
<form target="remember" method="post" action=".">
<input type="text" id="path" size='110'>
<button type="submit" onclick="doyouthing();">your button</button>
</form>
I have a page with many forms on it. could be 1..200. None of these forms have buttons and they are built programatically. I am using jquery to submit all the forms that are checked.
function FakeName()
{
$("input:checked").parent("form").submit();
}
My forms look like:
<form name="FakeForm<%=i%>" action="javascript:void%200" onSubmit="processRow(<%=i%>)" method="post" style="margin:0px;">
<input type="checkbox" name="FakeNameCheck" value="FakeNameCheck"/>
<input type="hidden" name="FakeNum" value="<%= FakeNum%>"/>
<input type="hidden" name="FakeId" value="<%=FakeIdr%>"/>
<input type="hidden" name="FakeAmt" value="<%=FakeAmount%>"/>
<input type="hidden" name="FakeTrans" value="FakeTrans"/>
</form>
Note: action is set to "javascript:void%200" so that it posts to a fake page. I want to handle my own posting in processRow.
OnSubmit never gets called and therefore ProcessRow never gets called.
Obviously all the names of the functions and variables have been changed to protect their identity :D
How can I get a function in each form to fire when I call submit programmatically.
The onsubmit handler is deliberately not triggered when you programatically submit the form. This is to avoid infinite recursion if an event handler would cause the event to be triggered again (and therefore the event handler to be called again)
However, of course you can call the processRow() function yourself in place of the .submit() call.
You're allowed to have inputs outside of forms. One school of thought is that a <form> shouldn't be a <form> if it's not intended to be submitted to the server via HTML.
Look up dispatchEvent and it's equivalent fireEvent. It's not the easiest thing in the world to use, but I think that's what you are looking for.
I'm surprised that there's no library that helps with this easily. Prototype (the one I've used the most) comes closest with a .fire() method on elements.
Looks like I may be able to do this:
<form name="FakeForm<%=i%>" action="javascript:processRow(<%=i%>)" method="post" style="margin:0px;">
<input type="checkbox" name="FakeNameCheck" value="FakeNameCheck"/>
<input type="hidden" name="FakeNum" value="<%= FakeNum%>"/>
<input type="hidden" name="FakeId" value="<%=FakeIdr%>"/>
<input type="hidden" name="FakeAmt" value="<%=FakeAmount%>"/>
<input type="hidden" name="FakeTrans" value="FakeTrans"/>
</form>
Are there any drawbacks to this?