Bruce Gust
asked on
Why does this function not work?
Here's my code:
This should be a slam dunk in that I'm simply copying and pasting from this site: http://www.the-art-of-web.com/javascript/doublesubmit/
But what you see above doesn't work and I don't know why. Can you help a brother out? What am I missing?
<!DOCTYPE html>
<html lang="en">
<head>
<title>Form Test</title>
<script type="text/javascript">
function checkForm(form) // Submit button clicked
{
//
// check form input values
//
form.myButton.disabled = true;
form.myButton.value = "Please wait...";
return true;
}
function resetForm(form) // Reset button clicked
{
form.myButton.disabled = false;
form.myButton.value = "Submit";
}
</script>
</head>
<body>
<form method="POST" onsubmit="return checkForm(this);">
<input type="submit" name="myButton" value="Submit">
<input type="button" value="Reset Button" onclick="resetForm(this.form);">
</form>
</body>
</html>
This should be a slam dunk in that I'm simply copying and pasting from this site: http://www.the-art-of-web.com/javascript/doublesubmit/
But what you see above doesn't work and I don't know why. Can you help a brother out? What am I missing?
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
I'd recommend a structure like what I have below, where the event binding is done in the JavaScript instead of inline with the HTML. Note: I changed the submit button to just a button. This way, you don't have to interrupt the default action of the submit. You can just bind a click event to the button, and if your conditional checks have been met, you can then submit the form using form.submit();
Here is a JS Fiddle Demo
HTML
JS
Here is a JS Fiddle Demo
HTML
<form id="myForm" method="POST">
<input id="mySubmit" type="button" name="myButton" value="Submit">
<input id="myReset" type="button" value="Reset Button">
</form>
JS
var form = document.getElementById("myForm");
var btnSubmit = document.getElementById("mySubmit");
btnSubmit.addEventListener('click', checkForm);
function checkForm() {
//
// check form input values
//
console.log('here');
form.myButton.disabled = true;
form.myButton.value = "Please wait...";
//form.submit(); //use this to submit the form
}
var btnReset = document.getElementById("myReset");
btnReset.addEventListener('click', resetForm);
function resetForm()
{
console.log('here 1');
form.myButton.disabled = false;
form.myButton.value = "Submit";
}
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Alright, guys!
Thanks for your input! A couple of questions:
This works:
One of the reasons I was at a loss is because the code didn't look familiar. After hearing your counsel it makes sense, given the fact that y'all were in agreement as far as the code being antiquated.
So, while this does work, I would much rather just the document.getElementById dynamic. Yet, this...
...doesn't work and I don't know why.
Thoughts?
BTW: Zephyr! When I tried your suggestion on JFiddle, I got this:
I'm probably missing something very obvious, but I didn't see what.
Looking forward to seeing what you guys have to say.
Thanks!
Thanks for your input! A couple of questions:
This works:
<!DOCTYPE html>
<html lang="en">
<head>
<title>Form Test</title>
<script type="text/javascript">
function checkForm(form) // Submit button clicked
{
//
// check form input values
//
form.myButton.disabled = true;
form.myButton.value = "Please wait...";
return true;
}
function resetForm(form) // Reset button clicked
{
form.myButton.disabled = false;
form.myButton.value = "Submit";
}
</script>
</head>
<body>
<!--<form method="POST" onsubmit="return checkForm(this);">-->
<form method="POST" name="myForm" onsubmit="return checkForm(this) && false;">
<input type="submit" id="theButton" name="myButton" value="Submit">
<input type="button" value="Reset Button" onclick="resetForm(this.form);">
</form>
</body>
</html>
One of the reasons I was at a loss is because the code didn't look familiar. After hearing your counsel it makes sense, given the fact that y'all were in agreement as far as the code being antiquated.
So, while this does work, I would much rather just the document.getElementById dynamic. Yet, this...
<!DOCTYPE html>
<html lang="en">
<head>
<title>Form Test</title>
<script type="text/javascript">
var form = document.getElementById("myForm");
var btnSubmit = document.getElementById("mySubmit");
btnSubmit.addEventListener('click', checkForm);
function checkForm() {
//
// check form input values
//
console.log('here');
form.myButton.disabled = true;
form.myButton.value = "Please wait...";
//form.submit(); //use this to submit the form
}
var btnReset = document.getElementById("myReset");
btnReset.addEventListener('click', resetForm);
function resetForm()
{
console.log('here 1');
form.myButton.disabled = false;
form.myButton.value = "Submit";
}
</script>
</head>
<body>
<form id="myForm" method="POST">
<input id="mySubmit" type="button" name="myButton" value="Submit">
<input id="myReset" type="button" value="Reset Button">
</form>
</body>
</html>
...doesn't work and I don't know why.
Thoughts?
BTW: Zephyr! When I tried your suggestion on JFiddle, I got this:
I'm probably missing something very obvious, but I didn't see what.
Looking forward to seeing what you guys have to say.
Thanks!
Not sure if I missed the point here but your original code would "work" if you replaced the return true on line 15 with return false - if by work you mean you want the button to change its text and stay on the same page.
When you return true from an event handler it proceeds with the default action - in this case a submit so the page posts to itself (as there is no action attribute) and the effect of changing the button is lost.
When you return false it cancels the default behaviour of submitting the form.
In your second example there are a couple of things that went wrong.
Firstly, JavaScript runs as it is loaded. If you have this line
Two options
1. Move the code to after the html for mySubmit (before the closing </body> tag)
2. Put the code inside a window onload
Having said that none of the globals are required - you could achieve the same result with this code
Also, changing the submit button to type submit so we can bind to the submit event on the form.
(Above should be good back to IE9 - if you want to support ancient history then post back for the remedy)
There is also a jQuery solution which is provided for reference
When you return true from an event handler it proceeds with the default action - in this case a submit so the page posts to itself (as there is no action attribute) and the effect of changing the button is lost.
When you return false it cancels the default behaviour of submitting the form.
In your second example there are a couple of things that went wrong.
Firstly, JavaScript runs as it is loaded. If you have this line
var btnSubmit = document.getElementById("mySubmit");
Then mySubmit needs to exist before this line runs. As this line appears before the markup for mySubmit an error is generated because the JavaScript code cannot find an element with that ID.Two options
1. Move the code to after the html for mySubmit (before the closing </body> tag)
2. Put the code inside a window onload
window.onload = function() {
// initialisation here
}
The above is provided for reference - unless you know what you are doing with chaining and preserving existing onload code this might have side effects down the line. The preferred method is to use addEventListenervar form, btnSubmit, btnReset;
window.addEventListener('load', init);
function init() {
form = document.getElementById("myForm");
btnSubmit = document.getElementById("mySubmit");
btnSubmit.addEventListener('click', checkForm);
btnReset = document.getElementById("myReset");
btnReset.addEventListener('click', resetForm);
}
Note the declaration of form, btnReset and btnSubmit outside of init() - if you do it inside then it's scope is local to the init function and references to these var's in other functions will fail.Having said that none of the globals are required - you could achieve the same result with this code
<!DOCTYPE html>
<html lang="en">
<head>
<title>Form Test</title>
<script type="text/javascript">
window.addEventListener('load', init);
function init() {
form = document.getElementById("myForm");
document.getElementById("mySubmit")
.addEventListener('click', checkForm);
document.getElementById("myReset")
.addEventListener('click', resetForm);
}
function checkForm(evt) {
//
// check form input values
//
console.log('here');
myForm.myButton.disabled = true;
myForm.myButton.value = "Please wait...";
// if fail then prevent form submit
evt.preventDefault();
//form.submit(); //use this to submit the form
}
function resetForm()
{
console.log('here 1');
myForm.myButton.disabled = false;
myForm.myButton.value = "Submit";
}
</script>
</head>
<body>
<form id="myForm" method="POST">
<input id="mySubmit" type="button" name="myButton" value="Submit">
<input id="myReset" type="button" value="Reset Button">
</form>
</body>
</html>
Note the chaining of the getElementById to addEventListener and the use of myForm (id of your form) directly to reference the form.Also, changing the submit button to type submit so we can bind to the submit event on the form.
(Above should be good back to IE9 - if you want to support ancient history then post back for the remedy)
There is also a jQuery solution which is provided for reference
<script src="http://code.jquery.com/jquery.js"></script>
<script>
$(function() {
$('form').submit(function(e) {
$('#mySubmit').val('Please wait ...').prop({disabled: true});
// return true if good
return false;
});
$('#myReset').click(function() {
$('#mySubmit').val('Submit').prop({disabled: false});
});
});
</script>
ASKER
Julian! Thank you! I'm going through your code and google-ing things to better understand not just what you're doing, but why it works. With that in mind, one question: What's the significance / role of "window.addEventListener(' load', init);?" Is that similar to $('document').ready(functi on(){}); in JQuery?
And, just to check my understanding, since JavaScript / JQuery are both processing things in chronological order (going back to what you said earlier, as far as var btnSubmit = document.getElementById("m ySubmit"); not going to work if the button hasn't loaded yet), the "window.addEventListener" is a workaround or a "safety feature," in that it prevents the function from attempting to work prior to the page being fully loaded.
Yes?
And, just to check my understanding, since JavaScript / JQuery are both processing things in chronological order (going back to what you said earlier, as far as var btnSubmit = document.getElementById("m
Yes?
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Thanks, guys! Very much appreciate the solution as well as the explanations!
You are welcome.
On clicking submit, this error comes up in F12 developer tools console:
This tells me that the function is not in the right scope. Move it outside of document ready, and it works.
Here is a JS Fiddle Demo. Pay attention to the Load Type setting I have in the demo.
I changed it from OnLoad to No Wrap, which is the same thing as moving it outside of document ready. In other words, these functions need global scope.
That being said, this structure of calling JavaScript functions inline is ... outdated. More recent thought is to keep "separation of concerns". I will post a followup answer with some suggestions.