Why Form Elements should not be named submit? - javascript

I figured out through debugging that I should not name any Form Elements name="submit", but even after searching I didn't find any good explanation of why?
See simple code example below:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title></title>
</head>
<body>
<form action="javascript:alert('submitted');" method="post" id="test-form">
<label>Name</label>
<input type="text" name="name-field" value="" />
<input type="submit" name="submit" value="Submit Button" /> <!-- name should not be "submit" -->
<p>Submit Link</p>
</form>
</body>
</html>
If you Press Enter while on any Form Element or Click the
Submit Button, it will work.
If you Click on the Submit Link, it will have error
Unhandled Error: 'document.getElementById('test-form').submit' is not a function
If you simply rename your Submit Button to anything other than name="submit" (even if you just capitalize some part of it) or just remove the name="submit" attribute, then both the Submit Button and Submit Link will work.
I tried this in the latest version of Internet Explorer, Firefox, Opera, Chrome, and Safari. All of them have consistent behavior with regards to this.
As you can see in my code example, there is no involvement of jQuery or any other JavaScript library.
I would appreciate the explanation. Thanks

If you check the Mozilla docs here : https://developer.mozilla.org/en-US/docs/DOM/HTMLFormElement
You will see that forms have a .submit() method.
In addition, forms are also populated with the fields within the form.
(Here is one example:
http://www.devbay.com/articles/javascript/accessing-form-elements-array-with-javascript/
I can't find any reference that it should happen, only that it does.)
So, when you make an element called submit it over-rides the forms built-in submit() method -- and since the element is, well, not a function, you get that error message.

Say your form is named "foo" and you have a field "firstName".
foo.firstName is that field in the form.
foo.submit() will submit that form, because submit is a method on forms.
If you redefine submit to be a form field you overwrite the submit method.

submit would be the form input type and i think is also used as an identifier in javascript. So naming a submit button "submit" makes the use of "submit" in javascript ambiguous

Related

Javascript file is re-loaded when pressing enter button inside an <form> element. Why?

I have this html sample code
<html>
<head>
<title>Form Test</title>
<script src="./testScript.js"></script>
</head>
<body>
<form>
<input id="textField" type="text" placeholder="Type in your name">
</form>
</body>
</html>
The testScript.js file contains only one line: alert("hello");
When I write something inside the input element and I press on enter button, the javascript file is reloaded and the alert is triggered. I noticed that when I remove the form, the reloading will not be triggered.
Why this happens? and How to prevent the reloading of javascript files when pressing enter button inside a form?
Without specific attributes, the method of the form will be get, so pressing enter in an input field will submit the form through the GET method. The page will thus reload and the javascript file loaded, and the alert triggered.
I think your code exists an error.
You didn't close the input element. Just modify the html like this:
<input id="textField" type="text" placeholder="Type in your name"/>

Form Button Submit IE Issue

I have a form that is submitted by a button like this:
<input type="submit" form="billing-form" value="xyz" name="abc">
That submits a form like this:
<form method="POST" id="billing-form" action="something.php">
//bunch of fields here
</form>
The button submits the form fine in most browsers except IE.
Any ideas how to make this work in IE?! The button unfortunately has to be outside of the form itself which is why I'm using the billing-form name to reference.
Thanks,
NCoder
Well if using simple script is not a problem then you can simply use an input button and submit the from using js
<input type="button" form="billing-form" value="xyz" name="abc" onclick="submitForm();">
function submitForm()
{
document.getElementById('billing-form').submit();
}
Not going to work with the submit button outside the form without using javascript. See This question and answer.

Trigger autocomplete without submitting a form

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>

Javascript acting funny in Internet Explorer

I have a website where I want people to be able to type something in a text box and get sent to that directory based on what they entered.
Say customer numbers, so we have customer # 155. His invoices are in folder /invoices/155 directory. I want him to be able to type in his customer # and be directed with a button click to his directory with all his invoices.
Now I have coded the below code but it only works when I click on the button with the mouse. In Internet Explorer When I press enter it gives me a bunch of gook in the address bar and doesn't do anything. It looks like this in the address bar:
file:///C:/Users/My%20Name/Desktop/test.html?dir=%2Finvoices%2F&userinput=155
Instead of loading the folder /invoices/155/.
<html>
<head>
<title>test</title>
</head>
<form name="goto" action="">
<input name="dir" type="hidden" value="/invoices/">
<input name="userinput" type="text"> <input type="button" value="try me" onclick="window.location=this.form.dir.value+userinput.value">
</form>
Can anyone tell me what is wrong with the code and what can I do to fix it? Thanks in advance.
In some browsers the form will be posted when you press enter, eventhough there is no submit button. Use a submit button, and catch the submit, then you handle all cases:
<form name="goto" action="" onsubmit="window.location=this.dir.value+this.userinput.value;return false;">
<input name="dir" type="hidden" value="/invoices/">
<input name="userinput" type="text"> <input type="submit" value="try me">
</form>
It won't work, if you use file protocol. Especially in IE. You need a real web server.
And to let a customer type in his on id is extremely insecure. Anyone could type in any id. Use a login.
It is really*** important to sanitize every user input to prevent abuse.
It is a long way to go.
I think you should go for onsubmit on <form>
<!DOCTYPE html>
<html>
<head>
<title>test</title>
<script>
function handleFormSubmit(form)
{
window.location = form.dir.value + form.userinput.value;
return false;
}
</script>
</head>
<body>
<form onsubmit="return handleFormSubmit(this)">
<input name="dir" type="hidden" value="/invoices/">
<input name="userinput" type="text">
<input type="submit" value="try me" >
</form>
</body>
</html>​​​​​​​
BTW:
Inlining javascript is not so good. Use script tag or external .js-file.
Edit:
Oops! OK, the error was that I wrote this.form.dir but it needed to be this.dir because this already referred to the form, now that the javascript handler was on the form tag (onsubmit="<handler-code>"). That works - http://jsfiddle.net/Q875a/
Edit 2:
Inlining javascript means that you write javascript code in your html tags (form, input,...) in the onXXX attributes - it's not readable. Having your script in a script tag within a handler-function (i.e. handleFormSubmit) makes it much more readable especially if your site gets more and more script in it - see current script and onsubmit-attribute.
Finally, if you want to to take a step further to crossbrowser, powerful javascript development you should take a look at jQuery - it's imho the door to really professional and exiting javascript programming!
JSFiddle to test:
http://jsfiddle.net/yNTK5/
jQuery-links concerning the topic:
http://api.jquery.com/submit/
http://api.jquery.com/on/
http://api.jquery.com/ready/

IE7 form not prompted for remember password when submitted through javascript

I have a website where we use Javascript to submit the login form. On Firefox it prompts the user to remember their password, when they login, but on IE7 it doesn't.
After doing some research it looks like the user is only prompted in IE7 when the form is submitted via a Submit control. I've created some sample html to prove this is the case.
<html>
<head>
<title>test autocomplete</title>
<script type="text/javascript">
function submitForm()
{
return document.forms[0].submit();
}
</script>
</head>
<body>
<form method="GET" action="test_autocomplete.html">
<input type="text" id="username" name="username">
<br>
<input type="password" id="password" name="password"/>
<br>
Submit
<br>
<input type="submit"/>
</form>
</body>
</html>
The href link doesn't get the prompt but the submit button will in IE7. Both work in Firefox.
I can't get the style of my site to look the same with a submit button, Does anyone know how to get the remember password prompt to show up when submitting via Javascript?
Why not try hooking the form submission this way?
<html>
<head>
<title>test autocomplete</title>
<script type="text/javascript">
function submitForm()
{
return true;
}
</script>
</head>
<body>
<form method="GET" action="test_autocomplete.html" onsubmit="return submitForm();">
<input type="text" id="username" name="username">
<br>
<input type="password" id="password" name="password"/>
<br>
Submit
<br>
<input id="FORMBUTTON" type="submit"/>
</form>
</body>
</html>
That way your function will be called whether the link is clicked or the submit button is pushed (or the enter key is pressed) and you can cancel the submission by returning false. This may affect the way IE7 interprets the form's submission.
Edit: I would recommend always hooking form submission this way rather than calling submit() on the form object. If you call submit() then it will not trigger the form object's onsubmit.
Did you try putting in url in the href and attaching a click event handler to submit the form and returning false from the click handler so that the url does not get navigates to.
Alternatively hidden submit button triggered via javascript?
You could try using the HTML <button> tag instead of a link or a submit button.
For example,
<button type="submit">Submit</button>
The <button> tag is much easier to style than the standard <input type="submit">. There are some cross-browser quirks but they are not insurmountable.
A really great article about the use of <button> can be found at particletree: Rediscovering the button element

Categories

Resources