I'm learning JavaScript and am unable to make a button inside of a form that doesn't submit the form. There is a similar question here but the most popular answer to specify type="button" doesn't work in my case and other answers involve jQuery, which I would like to leave out for now.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<script type="text/javascript">
function submit(){
alert("Yo")
}
</script>
</head>
<body>
<form name="myForm" onsubmit="submit()">
<input type="button" value="Submit!" onClick="submit()" />
</form>
</body>
</html>
Since you're not using a type="submit" the only reason your form would submit anything is because you're literally calling the submit() method when the button is clicked. (well, sort of. It's actually form.submit() - the method you created is window.submit()).
By default, an input of type="button" will not do a form submission unless you literally call form.submit()
Pass along the event as an argument in your submit function, and prevent its default behaviour:
function submit(event) {
event.preventDefault();
alert('Yo');
}
onClick='submit(event)'
Dating from the introduction of Javascript by Netscape Corporation, form element event handlers defined as HTML attribute values were provided with a special scope chain which searches properties of the element clicked and the form element ahead of searching the global object. [This was a convenience for web programmers and predated the introduction of a Document Object Model with standardized methods for access and manipulation.] Hence
<input type="button" value="Submit!" onClick="submit()" />
when clicked executes the anonomous function created from the HTML attribute string:
function( event) { submit()}
which searches its scope chain for submit and finds it as a property of the enclosing form object. Possible solutions include
explicitly specifying the global version of the function to execute:
onclick="window.submit()"
naming the global function something else, say "preSubmit", which does not conflict with the property of the form object:
onclick="preSubmit()"
adding the click event handler to the button in javascript after the button element has been created (only function specified in HTML have a special scope chain).
Section `19.1.6. Scope of Event Handlers" within chapter 19 of "Javascript the Definitive Guide" from O'Reilly is the only link that I have been able to find which discusses this.
updated after #progysm's comment on another answer
The scope chain of an HTML provided event handler is now covered in the HTML5 standard, under internal raw uncompiled handler, list item 1.10, which indicates the lexical scope of the handler includes the element clicked, the form it belongs to (if any) and the document object. I would caution against relying on this too heavily: some browsers used to include every parent object of a clicked element in its scope chain, not just its form and document.
To prevent your button from submitting, you can either:
Use preventDefault() on the onsubmit event of the <form> or
Use return false at the end of the operation on the onclick event of the button.
The code:
<html>
<head></head>
<body>
<form name = "myForm" method = "POST">
<input name = "button" type="submit" value="Submit!"/>
</form>
<script type = "application/javascript">
document.forms.myForm.onsubmit = function(e) {
e = e || event;
e.preventDefault();
}
document.forms.myForm.button.onclick = function () {
// Your code
return false; // Prevents the button from trying to submit
}
</script>
</body>
</html>
Notes:
Be sure to use the method attribute in the <form> tag as it's required.
e = e || event means that e will be equal to e in all the browsers that recognise it and equal to event in browsers that recognise event.
document.forms.[form name].[input name] is another way to get an element based on its name, in contrast to document.getElementById() which requires the id of the element, which have not set in your HTML.
You can test the code's functionality live with the following snippet:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head></head>
<body>
<!-- The form we don't want to submit -->
<form name = "myForm" method = "POST">
<input name = "button" type="submit" value="I will not submit!"/>
</form>
<!-- The form we want to submit -->
<form name = "myForm2" method = "POST">
<input name = "button2" type="submit" value="I will submit!"/>
</form>
<script type = "application/javascript">
// For the form we don't want to submit
document.forms.myForm.onsubmit = function(e) {
e = e || event;
e.preventDefault();
}
document.forms.myForm.button.onclick = function () {
console.log("NOT Submitted!");
return false;
}
// For the form we want to submit
document.forms.myForm2.button2.onclick = function () {
console.log("Submitted!");
}
</script>
</body>
</html>
function onFormSubmit()
{
console.log('FORM SUBMITTED');
return false;
}
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<body>
<form name="myForm" onsubmit="return onFormSubmit()">
<input type="submit" value="Submit form! [input type = submit]" /><br />
<input type="button" value="Submit form! [input type = button, onclick = form.submit]" onClick="return onFormSubmit();" /><br />
<!-- in real test change onClick behavior
return onFormSubmit();
to:
form.submit();
Here I used onFormSubmit() because when you calling form.submit() browser doesn't dispatch onsubmit event -->
<button>Submit form! [button]</button><br />
Submit form! [a, onclick = form.submit]<br /><br />
<input type="button" value="Click me, no submit! [input type = button]" /><br />
</form>
</body>
</html>
If you wish to conditionally consume the event or not, simply return true or false from your handler function, like so...
JavaScript:
function validate() {
var valid = true;
// the following two validation functions would return a Boolean.
valid = valid && validateUsername();
valid = valid && validatePassword();
// If validation is fine, return true and this allows post to continue.
// If validation is not fine, return false and this disallows the submission from going ahead.
return valid;
}
HTML:
<form name="frmTest" id="frmTest"
method="post" action="example.action"
onsubmit="return validate();">
</form>
If you don't need it to be conditional, just return false, of course.
This solution works in native javascript. Doesn't prevent return key in inputs, it does what it should - stop a form from submitting on enter
function preventReturnKeyFormSubmit(){
//listen to key press events
window.addEventListener('keydown', function(e){
//set default value for variable that will hold the status of keypress
pressedEnter = false;
//if user pressed enter, set the variable to true
if(event.keyCode == 13)
pressedEnter = true;
//we want forms to disable submit for a tenth of a second only
setTimeout(function(){
pressedEnter = false;
},100)
})
//find all forms
var forms = document.getElementsByTagName('form')
//loop through forms
for(i = 0; i < forms.length; i++){
//listen to submit event
forms[i].addEventListener('submit', function(e){
//if user just pressed enter, stop the submit event
if(pressedEnter == true) {
e.preventDefault();
return false;
}
})
}
}
//run this function inside document onload/domready/ or if using jquery .ready()
preventReturnKeyFormSubmit()
Simply make it return the function, and return false
<script type="text/javascript">
function submit(){
alert("Yo");
return false;
}
</script>
</head>
<body>
<form name="myForm" onsubmit="submit()">
<input type="button" value="Submit!" onClick="return submit()" />
</form>
</body>
</html>
Related
Due to the layout of my page I would like to place a custom element outside of a form.
Can I make something like <my-custom-element form="foo"> work?
Presuming you want the submit button to return the value of your element even though it is outside the form. This is one way, there are many more (including using the function here called addExtras() to dynamically append your external name/value pair(s) to the form).
<my-custom-element> <input name="custom" id="custom" value="foo"></my-custom-element>
<form id="myForm" onsubmit="return addExtras()" method="post">
<input type="hidden"" name="customItem" id="customItem" />
<input name="anotherField" value="india" />
<button type="submit">submit</button>
</form>
<script>
function addExtras() {
document.getElementById("customItem").value = document.getElementById("custom").value;
return true;
}
// ==========================================================
//Code to display the submitted items, and prevent submission for test purposes
//Not needed for production
document.getElementById("myForm").addEventListener('submit', function (e) {
//prevent the normal submission of the form
e.preventDefault();
for (var i = 0; i < document.getElementById("myForm").elements.length; i++) {
var e = document.getElementById("myForm").elements[i];
console.log(e.name, e.value)
}
});
</script>
I don't know how to link the following condition-reactions to passid form input id:
I don't know where to put the document.querySelector() method so that indexed contion-reactions will be associated with it.
Here is the code:
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Password - form</title>
</head>
<body>
<form>
<label>Password</label>
<input type="password" id="passid" />
<br>
<input type="submit" value="Sign In" />
</form>
<script>
function passType() {
var password = ["p1", "p2", "p3", "p4", "p5"];
if (password.indexOf > -1) {
alert("That's great! Thank you!");
} else {
alert("Wrong, try again");
}
if (password.indexOf > -1) {
alert("It's wrong, you have one more try...");
} else {
alert("Get out now!");
window.close();
}
}
passType();
</script>
</body>
</html>
How should this be done?
These are some points that I would want to focus on :
To select a particular element using the query selector, remember these :
If you happen to know the id of the element, use document.getElementById(id). This is the most prominent way of selection, as usually id is unique for all elements.
If you happen to know the class of the element, use document.getElementsByClassName(class). This method has certain amount of risk, as there could be more than one element with the same class.
If you happen to know the tagName of the element, use document.getElementsByTagName(tag).
The easiest way to achieve element selection is by using document.querySelector('tag'/ '.class'/ '#id'). You can refer here for more about the same.
Now, you need to understand that your function passType(), which here validates the entered password based in the array of passwords you have defined, needs to be called only after the user has input the password and click the Sign In button.
In order to achieve this, you will have to bind the submit event to an EventListener. This can be achieved by using document.querySelector('form').addEventListener('submit', passType);
Now finally, as per the code snippet you provided, you want to give the user a second chance in case the user enters a wrong password at first attempt. For this, you will have to store the attempt counts in a variable. Also, the EventListener of the submit action button keeps bubbling, and in order to prevent it, you need to use event.preventDefault()
Keeping all this in mind, I believe this will solve your problem. Here is the rectified code snippet :
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Password - form</title>
</head>
<body>
<form>
<label>Password</label>
<input type="password" id="passid"/>
<br>
<input type="submit" value="Sign In"/>
</form>
<script>
var attemptCount = 0;
function passType(event) {
event.preventDefault();
var enteredValue = document.querySelector('form').querySelector('#passid').value;
var password = ['p1', 'p2', 'p3', 'p4', 'p5'];
if (password.indexOf(enteredValue) > -1) {
alert("That's great! Thank you!");
}
else {
attemptCount++;
alert('Wrong, try again');
if (attemptCount <= 1) {
alert("It's wrong, you have one more try...");
document.querySelector('form').querySelector('#passid').value = '';
} else {
alert('Get out now!');
window.close();
}
}
}
document.querySelector('form').addEventListener('submit', passType);
</script>
</body>
</html>
Feel free to ask any queries you have on the same.
How to access form using query selector?
let frm = document.querySelector('form');
Then Listen for its submit event.
frm.addEventListener('submit', passType);
How can you access the input password?
You need to make changes to your function. First add the following to the top of your "passType" function. The following snippet saves the user input into the variable pass.
let p = frm.querySelector('#passid');//Get the DOM node
let pass = p.value;//Get the input value
Now Modify if (password.indexOf > -1) to if (password.indexOf(pass) > -1) to check for actual input.
DEMO
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Password - form</title>
</head>
<body>
<form>
<label>Password</label>
<input type="password" id="passid" />
<br>
<input type="submit" value="Sign In" />
<!-- We also have input type = "button" and events for both >>> onsubmit & onclick. -->
</form>
<script>
function passType() {
let p = frm.querySelector('#passid');
let pass = p.value;
var password = ["p1", "p2", "p3", "p4", "p5"];
if (password.indexOf(pass) > -1) {
alert("That's great! Thank you!");
} else {
alert("Wrong, try again");
if (password.indexOf(pass) > -1) {
alert("It's wrong, you have one more try...");
} else {
alert("Get out now!");
window.close();
}
}
}
let frm = document.querySelector('form');
frm.addEventListener('submit', passType);
</script>
</body>
</html>
I guess you're asking how to get the value the user typed into the password field. That's document.getElementById("passid").value. So you would write:
if (password.indexOf(document.getElementById("passid").value) > -1) {
alert("That's great! Thank you!");
}
Note that calling passType() in the top-level of the script won't work. That will run when the page is first loaded, not wait for the user to fill in the password. You should call it when the user submits the form. You should do:
document.querySelector("form").addEventListener("submit", passAll);
You should also change the passAll() function so it calls Event.preventDefault() if the user enters an incorrect password, to prevent submitting the form. See
return false on addEventListener submit still submits the form?
Also, checking a password in client-side Javascript is not very secure. There's nothing stopping the user from modifying the script or bypassing it. Passwords should be checked on the server, so that the user cannot override it.
If you're looking for a way to do something with the password field upon form submission you might want something along these lines:
// listen for submit events on the form
document.querySelector('form').addEventListener('submit', doSubmit);
// our form submit handler
function doSubmit(event) {
// prevent submission
event.preventDefault();
event.stopPropagation();
// get the password field
// event.target is the form
// could alternatively query by id using document.getElementById('passid')
var passwordField = event.target.querySelector('#passid');
// do something with the field or its value
console.log(passwordField.value);
return false;
}
<form>
<label>Password</label>
<input type="password" id="passid" />
<input type="submit" value="Sign In" />
</form>
i have create eway paynow button within form.
<form action="?" method="POST">
Name: <input type="text" name="customer_name" value="" />
<script src="https://secure.ewaypayments.com/scripts/eCrypt.js"
class="eway-paynow-button"
data-publicapikey="epk-6AEE4269-0010-4415-A327-8064928AEFD0"
data-amount="0"
data-currency="AUD"
data-allowedit="true"
data-resulturl="http://example.com/responseMsg.php">
</script>
</form>
i need to check whether customer_name field empty or not before load eway payment
form. if customer_name field empty don't load eway payment form.how do i do this??can i run javascript to validate this form?
The Pay Now button doesn't provide a hook to run a function before opening the payment form, nor does it use event listeners at the moment. The solution here is to:
Capture the original onclick handler
Add a new event listener which performs validation, then calls the original onclick if successful.
I've stuck to pure JS for this, jQuery would allow a cleaner implementation :-)
Also note I've removed the data-resulturl attribute and moved the URL to form tag, otherwise the window may just redirect without submitting.
<form action="http://example.com/responseMsg.php" method="POST">
Name: <input type="text" name="customer_name" value="" />
<script src="https://secure.ewaypayments.com/scripts/eCrypt.js"
class="eway-paynow-button"
data-publicapikey="epk-6AEE4269-0010-4415-A327-8064928AEFD0"
data-amount="10"
data-currency="AUD"
data-allowedit="true"
data-submitform="yes">
</script>
</form>
<script>
window.onload = function() {
// Find the eWAY Pay Now button - note getElementsByClassName is IE9+
var ewayButton = document.getElementsByClassName("eway-button")[0];
// save and remove old onclick
var oldeWAYclick = ewayButton.onclick;
ewayButton.onclick = null;
// Add new listener with validation
ewayButton.addEventListener("click", function(e){
// Stop form from submitting itself
e.preventDefault();
// Example validation
var name = document.forms[0]["customer_name"].value;
if (name == null || name == "") {
alert("Please complete all fields");
return;
}
// Display payment form
oldeWAYclick();
}, false);
};
</script>
My purpose: If the user field and password field are blank, I want to stop form submitting.
This is my Code that I am trying:
<!DOCTYPE html>
<html>
<head>
<script>
function doit() {
var usr = document.getElementById('ur').value;
var psw = document.getElementById('pw').value;
if ((usr.trim() == '') && (psw.trim() == '')) {
alert("cannot Submit form");
return false;
}
}
</script>
</head>
<body>
<form action="post.php" method="post" onsubmit="doit()">
User:
<input type="text" id="ur" name="user">
<br>
<br> Pass:
<input type="password" id="pw" name="pass">
<br>
<br>
<button>Submit</button>
</form>
</body>
</html>
I am learning JavaScript. Will be helpful if you correct the code with a little explanation why it is not working.
return false is working fine, the way you are calling that function is wrong.
<form action="post.php" method="post" onsubmit="doit()">
Just calls it, doesn't do anything with the return value
<form action="post.php" method="post" onsubmit="return doit()">
^
Will stop the form post on a false returned value.
Read this note on MSDN although it is not IE specific
You can override this event by returning false in the event handler. Use this capability to validate data on the client side to prevent invalid data from being submitted to the server. If the event handler is called by the onsubmit attribute of the form object, the code must explicitly request the return value using the return function, and the event handler must provide an explicit return value for each possible code path in the event handler function.
Now onto another important point.
Your if condition will only stop form submission when both the fields are blank, whereas it should do that even if any one of those two fields is blank. That && (AND) should be an || (OR), and at the end of your functions if nothing returned false, return true then.
onsubmit event accepts boolean values, since you are not returning anything so it assumes true by default. You need to add return in this event explicitly like mentioned below:
change
onsubmit="doit()">
to
onsubmit="return doit()">
Using addEventListener on submit with preventDefault()
document.form1.addEventListener( "submit", function(event) {
var user = this.querySelector("input[name=user]").value; // this = object of form1
var pass = this.querySelector("input[name=pass]").value;
if ( (user.trim() == "") || (pass.trim() == "") ) {
alert("cannot Submit form");
event.preventDefault();
} else {
alert("submit");
}
} );
<form action="" method="post" name="form1" >
Username: <input type="text" name="user" /><br><br>
Password: <input type="password" name="pass" /><br><hr>
<input type="submit" value="Submit" />
</form>
codepen
repl.it
I'm trying to stop a form from submitting using the submit eventlistener. My anonymous function runs but the form still submits, even with return false at the end of the function. There are no JS errors being thrown.
Am I making some stupid mistake?
<form id="highlight">
Row: <input type="text" name="rows" value="1" id="rows">
Column: <input type="text" name="cells" value="1" id="cells">
<input type="submit" name="Submit" value="Highlight" id="Submit">
</form>
<script>
var highlight_form = document.getElementById('highlight');
highlight_form.addEventListener('submit', function() {
alert('hi');
return false;
}, false);
</script>
I always call event.preventDefault() on event listeners that I want to cancel the event for, as well as return false. This always works for me.
<script>
var highlight_form = document.getElementById('highlight');
highlight_form.addEventListener('submit', function(event)
{
event.preventDefault();
alert('hi');
return false;
}, false);
</script>
To prevent form submission, I've always used the "onclick" event to call a javascript method which will do something and then submit from there. You can also setup the form as follows:
<form name="myForm" action="demo_form.asp" onsubmit="return validateForm()" method="post">
First name: <input type="text" name="fname">
<input type="submit" value="Submit">
</form>
Once submitted, the validateForm() method can prevent submission if necessary:
function validateForm()
{
var x=document.forms["myForm"]["fname"].value
if (x==null || x=="")
{
alert("First name must be filled out");
return false;
}
}
Well this is the way I would do it :
function validate (form)
{
// return false if some fields are not right
}
function setup_form_validation (form)
{
form.addEventListener (
'submit',
function (f) { // closure to pass the form to event handler
return function (evt) {
if (!validate (f)) evt.preventDefault();
// Return status doesn't work consistently across browsers,
// and since the default submit event will not be called in case
// of validation failure, what we return does not matter anyway.
// Better return true or nothing in case you want to chain other
// handlers to the submit event (why you would want do that is
// another question)
};
} (form),
false);
}
I would rather have a boolean holding the form validation status, though. Better update the status each time a field changes than do the check only when the user tries to submit the whole form.
And of course this will fail in IE8- and other older browsers. You would need yet another bloody event abstraction layer to make it work everywhere.