How to disable submit button once it has been clicked? - javascript

I have a submit button at the end of the form.
I have added the following condition to the submit button:
onClick="this.disabled=true;
this.value='Sending…';
this.form.submit();"
But when it moves to the next page, the parameters did not pass and null values are passed.

You should first submit your form and then change the value of your submit:
onClick="this.form.submit(); this.disabled=true; this.value='Sending…'; "

Probably you're submitting the form twice.
Remove the this.form.submit() or add return false at the end.
you should end up with onClick="this.disabled=true; this.value='Sending…';"

tested on IE11, FF53, GC58 :
onclick="var e=this;setTimeout(function(){e.disabled=true;},0);return true;"

You need to disable the button in the onsubmit event of the <form>:
<form action='/' method='POST' onsubmit='disableButton()'>
<input name='txt' type='text' required />
<button id='btn' type='submit'>Post</button>
</form>
<script>
function disableButton() {
var btn = document.getElementById('btn');
btn.disabled = true;
btn.innerText = 'Posting...'
}
</script>
Note: this way if you have a form element which has the required attribute will work.

Disabled HTML forms elements aren't sent along with the post/get values when you submit the form. So if you disable your submit button once clicked and that this submit button have the name attribute set, It will not be sent in the post/get values since the element is now disabled. This is normal behavior.
One of the way to overcome this problem is using hidden form elements.

the trick is to delayed the button to be disabled, and submit the form you can use
window.setTimeout('this.disabled=true',0);
yes even with 0 MS is working

Using JQuery, you can do this..
$("#submitbutton").click(
function() {
alert("Sending...");
window.location.replace("path to url");
}
);

If you disable the button, then its name=value pair will indeed not be sent as parameter. But the remnant of the parameters should be sent (as long as their respective input elements and the parent form are not disabled). Likely you're testing the button only or the other input fields or even the form are disabled?

Here's a drop-in example that expands on Andreas Köberle's solution. It uses jQuery for the event handler and the document ready event, but those could be switched to plain JS:
(function(document, $) {
$(function() {
$(document).on('click', '[disable-on-click], .disable-on-click', function() {
var disableText = this.getAttribute("data-disable-text") || 'Processing...';
if(this.form) {
this.form.submit();
}
this.disabled = true;
if(this.tagName === 'BUTTON') {
this.innerHTML = disableText;
} else if(this.tagName === 'INPUT') {
this.value = disableText;
}
});
});
})(document, jQuery);
It can then be used in HTML like this:
<button disable-on-click data-disable-text="Saving...">Click Me</button>
<button class="disable-on-click">Click Me</button>
<input type="submit" disable-on-click value="Click Me" />

I don't think you need this.form.submit(). The disabling code should run, then it will pass on the click which will click the form.

Another solution i´ve used is to move the button instead of disabling it. In that case you don´t have those "disable" problems.
Finally what you really want is people not to press twice, if the button is not there they can´t do it.
You may also replace it with another button.

function xxxx() {
// submit or validate here , disable after that using below
document.getElementById('buttonId').disabled = 'disabled';
document.getElementById('buttonId').disabled = '';
}

Your question is confusing and you really should post some code, but this should work:
onClick="this.disabled=true; this.value='Sending...'; submitForm(); return false;"
I think that when you use this.form.submit() it's doing what happens naturally when you click the submit button. If you want same-page submit, you should look into using AJAX in the submitForm() method (above).
Also, returning false at the end of the onClick attribute value suppresses the default event from firing (in this case submitting the form).

A better trick, so you don't lose the value of the button is
function showwait() {
document.getElementById('WAIT').style['display']='inline';
document.getElementById('BUTTONS').style['display']='none';
}
wrap code to show in a div
id=WAIT style="display:none"> text to display (end div)
wrap code to hide in a div
id=BUTTONS style="display:inline"> ... buttons or whatever to hide with
onclick="showwait();"
(end div)

In my case this was needed.
Disable submit button on form submit
It works fine in Internet Explorer and Firefox without it, but it did not work in Google Chrome.
The problem is that you are disabling the button before it can actually trigger the submit event.

I think easy way to disable button is :data => { disable_with: "Saving.." }
This will submit a form and then make a button disable, Also it won't disable button if you have any validations like required = 'required'.

In this working example, the user confirms in JavaScript that he really wants to abort. If true, the button is disabled to prevent double click and then the code behind which updates the database will run.
<asp:button id="btnAbort" runat="server" OnClick="btnAbort_Click" OnClientClick="if (!abort()) {return false;};" UseSubmitBehavior="false" text="Abort" ></asp:button>
I had issues because .net can change the name of the button
function abort() {
if (confirm('<asp:Literal runat="server" Text="Do you want to abort?" />')) {
var btn = document.getElementById('btnAbort');
btn.disabled = true;
btn.innerText = 'Aborting...'
return true;
}
else {
return false;
}
}
Because you are overriding the OnClick with OnClientClick, even if your validation method succeeds, the code behind wont work. That's why you set UseSubmitBehavior to false to make it work
PS: You don't need the OnClick if your code is in vb.net!

Okay, i did a lot of research on how to make this work perfectly.
So the best option is to create a set timeout for disabling a button onclick.
Now, the problem arise when there is a submit function running on the backend. Then the events become stacked in a queue and whenever the javascript "button.disabled == true"is added to the onclick event, only the first action(i.e. disabling the button) gets triggered and not the submit action which is running in the backend(This backend submit function can comprise of anything such as $.ajax).
For disabling Single button on click :
function() { //i always create annonymous function to avoid polluting global
space
var btn = document.getElementsByClassName("btn");
btn.onclick = function() {
setTimeout(function() {
backButton.disabled = true;
}, 0);
};
}
}();
This code will disable your button and also would run the function on the queue. timeout = 0 actually is used for firing subsequent backend tasks.
For disabling all btns in the screen :
(function() {
let i, element, list, o;
element = document.getElementsByClassName("classx");
if (element) {
element = element[0];
list = element.getElementsByTagName("button");
for (i = 0; i < list.length; i++) {
o = list[i];
o.onclick = function() {
setTimeout(function() {
let i;
for (i = 0; i < list.length; i++) {
list[i].disabled = true;
}
}, 0);
return true;
}
}
}
})();
This would help you disable all of the buttons present in the page. (Just use it according to your usecase.)
Also, this(disabled button) is a good use case for settimeout=0, functionality description as it will "defer" the call until the currently "stacked javascript events" are finished.
Thank you and hope this helps someone's in the future.

I did the trick. When set timeout, it works perfectly and sending all values.
$(document).ready(function () {
document.getElementById('btnSendMail').onclick = function () {
setTimeout(function () {
document.getElementById('btnSendMail').value = 'Sending…';
document.getElementById('btnSendMail').disabled = true;
}, 850);
}
});

Related

Submitting POST Request only once [duplicate]

I have a submit button at the end of the form.
I have added the following condition to the submit button:
onClick="this.disabled=true;
this.value='Sending…';
this.form.submit();"
But when it moves to the next page, the parameters did not pass and null values are passed.
You should first submit your form and then change the value of your submit:
onClick="this.form.submit(); this.disabled=true; this.value='Sending…'; "
Probably you're submitting the form twice.
Remove the this.form.submit() or add return false at the end.
you should end up with onClick="this.disabled=true; this.value='Sending…';"
tested on IE11, FF53, GC58 :
onclick="var e=this;setTimeout(function(){e.disabled=true;},0);return true;"
You need to disable the button in the onsubmit event of the <form>:
<form action='/' method='POST' onsubmit='disableButton()'>
<input name='txt' type='text' required />
<button id='btn' type='submit'>Post</button>
</form>
<script>
function disableButton() {
var btn = document.getElementById('btn');
btn.disabled = true;
btn.innerText = 'Posting...'
}
</script>
Note: this way if you have a form element which has the required attribute will work.
Disabled HTML forms elements aren't sent along with the post/get values when you submit the form. So if you disable your submit button once clicked and that this submit button have the name attribute set, It will not be sent in the post/get values since the element is now disabled. This is normal behavior.
One of the way to overcome this problem is using hidden form elements.
the trick is to delayed the button to be disabled, and submit the form you can use
window.setTimeout('this.disabled=true',0);
yes even with 0 MS is working
Using JQuery, you can do this..
$("#submitbutton").click(
function() {
alert("Sending...");
window.location.replace("path to url");
}
);
If you disable the button, then its name=value pair will indeed not be sent as parameter. But the remnant of the parameters should be sent (as long as their respective input elements and the parent form are not disabled). Likely you're testing the button only or the other input fields or even the form are disabled?
Here's a drop-in example that expands on Andreas Köberle's solution. It uses jQuery for the event handler and the document ready event, but those could be switched to plain JS:
(function(document, $) {
$(function() {
$(document).on('click', '[disable-on-click], .disable-on-click', function() {
var disableText = this.getAttribute("data-disable-text") || 'Processing...';
if(this.form) {
this.form.submit();
}
this.disabled = true;
if(this.tagName === 'BUTTON') {
this.innerHTML = disableText;
} else if(this.tagName === 'INPUT') {
this.value = disableText;
}
});
});
})(document, jQuery);
It can then be used in HTML like this:
<button disable-on-click data-disable-text="Saving...">Click Me</button>
<button class="disable-on-click">Click Me</button>
<input type="submit" disable-on-click value="Click Me" />
I don't think you need this.form.submit(). The disabling code should run, then it will pass on the click which will click the form.
Another solution i´ve used is to move the button instead of disabling it. In that case you don´t have those "disable" problems.
Finally what you really want is people not to press twice, if the button is not there they can´t do it.
You may also replace it with another button.
function xxxx() {
// submit or validate here , disable after that using below
document.getElementById('buttonId').disabled = 'disabled';
document.getElementById('buttonId').disabled = '';
}
Your question is confusing and you really should post some code, but this should work:
onClick="this.disabled=true; this.value='Sending...'; submitForm(); return false;"
I think that when you use this.form.submit() it's doing what happens naturally when you click the submit button. If you want same-page submit, you should look into using AJAX in the submitForm() method (above).
Also, returning false at the end of the onClick attribute value suppresses the default event from firing (in this case submitting the form).
A better trick, so you don't lose the value of the button is
function showwait() {
document.getElementById('WAIT').style['display']='inline';
document.getElementById('BUTTONS').style['display']='none';
}
wrap code to show in a div
id=WAIT style="display:none"> text to display (end div)
wrap code to hide in a div
id=BUTTONS style="display:inline"> ... buttons or whatever to hide with
onclick="showwait();"
(end div)
In my case this was needed.
Disable submit button on form submit
It works fine in Internet Explorer and Firefox without it, but it did not work in Google Chrome.
The problem is that you are disabling the button before it can actually trigger the submit event.
I think easy way to disable button is :data => { disable_with: "Saving.." }
This will submit a form and then make a button disable, Also it won't disable button if you have any validations like required = 'required'.
In this working example, the user confirms in JavaScript that he really wants to abort. If true, the button is disabled to prevent double click and then the code behind which updates the database will run.
<asp:button id="btnAbort" runat="server" OnClick="btnAbort_Click" OnClientClick="if (!abort()) {return false;};" UseSubmitBehavior="false" text="Abort" ></asp:button>
I had issues because .net can change the name of the button
function abort() {
if (confirm('<asp:Literal runat="server" Text="Do you want to abort?" />')) {
var btn = document.getElementById('btnAbort');
btn.disabled = true;
btn.innerText = 'Aborting...'
return true;
}
else {
return false;
}
}
Because you are overriding the OnClick with OnClientClick, even if your validation method succeeds, the code behind wont work. That's why you set UseSubmitBehavior to false to make it work
PS: You don't need the OnClick if your code is in vb.net!
Okay, i did a lot of research on how to make this work perfectly.
So the best option is to create a set timeout for disabling a button onclick.
Now, the problem arise when there is a submit function running on the backend. Then the events become stacked in a queue and whenever the javascript "button.disabled == true"is added to the onclick event, only the first action(i.e. disabling the button) gets triggered and not the submit action which is running in the backend(This backend submit function can comprise of anything such as $.ajax).
For disabling Single button on click :
function() { //i always create annonymous function to avoid polluting global
space
var btn = document.getElementsByClassName("btn");
btn.onclick = function() {
setTimeout(function() {
backButton.disabled = true;
}, 0);
};
}
}();
This code will disable your button and also would run the function on the queue. timeout = 0 actually is used for firing subsequent backend tasks.
For disabling all btns in the screen :
(function() {
let i, element, list, o;
element = document.getElementsByClassName("classx");
if (element) {
element = element[0];
list = element.getElementsByTagName("button");
for (i = 0; i < list.length; i++) {
o = list[i];
o.onclick = function() {
setTimeout(function() {
let i;
for (i = 0; i < list.length; i++) {
list[i].disabled = true;
}
}, 0);
return true;
}
}
}
})();
This would help you disable all of the buttons present in the page. (Just use it according to your usecase.)
Also, this(disabled button) is a good use case for settimeout=0, functionality description as it will "defer" the call until the currently "stacked javascript events" are finished.
Thank you and hope this helps someone's in the future.
I did the trick. When set timeout, it works perfectly and sending all values.
$(document).ready(function () {
document.getElementById('btnSendMail').onclick = function () {
setTimeout(function () {
document.getElementById('btnSendMail').value = 'Sending…';
document.getElementById('btnSendMail').disabled = true;
}, 850);
}
});

JavaScript & HTML Forms: Which button is the submitter?

I am writing a JavaScript function to pre-process form data. One thing I need to know is which of a number of submit buttons was used.
Roughly, the script has the following outline.
var form=document.querySelector('form#test');
form.onsubmit=processForm;
function processForm() {
// how did I get here
}
<form id="test">
<!-- usual stuff -->
<button type="submit" name="check">Check</button>
<button type="submit" name="doit">Do Stuff</button>
</form>
I know that I could attach the function to the individual submit buttons, but it would be more resilient if I attached it to the form itself.
Is there a form property or some other method for checking which submit button was used?
Thanks
You can attach click handler to each <button> element, create a variable to store clicked button name property, or reference to element, access property or element at submit event
function processForm(e) {
e.preventDefault();
console.log(curr) // `curr`: `name` of clicked `button"` element
}
var submit = document.querySelectorAll("button[type=submit]");
var curr;
for (var i = 0; i < submit.length; i++) {
submit[i].onclick = function(e) {
curr = e.target.name; // store reference to `name`, or element
}
}
Usually the clicked submit button is sent as it is considered active.
I believe that when there is only 1 submit button the form will submit on enter but when multiple it will only submit on click.
Thus in your backend, you can just check for the existence of either form button to know which button was used.
Relevant section of HTML rfc:
https://www.w3.org/TR/html401/interact/forms.html#h-17.13.2
However I wasn't able to find a good browser compatibility for this so your mileage may vary.
I believe the answer to my question is that you can’t. Once the submit event is activated, it doesn’t seem to know or care how it got there.
The only solution, as mentioned in my original question, is to attach a listener to the submit button[s].
Here is a stub of the processing code:
window.onload=init;
function init() {
var form=document.querySelector('form#test');
var submitButtons=form.querySelectorAll('button:not([type]),button[type="submit"],input[type="submit"]');
if(submitButtons.length) {
for(var i=0;i<submitButtons.length;i++) submitButtons[i].addEventListener('click',process);
}
function process(e) {
var submitter=this;
var form=this.form;
// etc
}
}
Oh well …

Stop onclick method running with jQuery

I have a button similar to below
<button id="uniqueId" onclick="runMethod(this)">Submit</button>
What I'm trying to do is stop the runMethod from running, until after I've done a check of my own. I've tried using the stopImmediatePropagation function, but this doesn't seem to have worked. Here's my jQuery:
$j(document).on('click', '#uniqueId', function(event) {
event.stopImmediatePropagation();
if(condition == true) {
// continue...
} else {
return false;
}
return false;
});
Note: runMethod basically validates the form, then triggers a submit.
What you want to do, especially in the way that you want to do it, requires a some sort of workaround that will always be a bit fiddly. It is a better idea to change the way the button behaves (e.g. handle the whole of the click event on the inside of the jQuery click() function or something along those lines). However I have found sort of a solution for your problem, based on the assumption that your user will first hover over the button. I am sure you can extend that functionality to the keyboard's Tab event, but maybe it will not work perfectly for mobile devices' touch input. So, bear in mind the following solution is a semi-complete workaround for your problem:
$(document).ready(function(){
var methodToRun = "runMethod(this)"; // Store the value of the onclick attribute of your button.
var condition = false; // Suppose it is enabled at first.
$('#uniqueId').attr('onclick',null);
$('#uniqueId').hover(function(){
// Check your stuff here
condition = !condition; // This will change to both true and false as your hover in and out of the button.
console.log(condition); // Log the condition's value.
if(condition == true){
$('#uniqueId').attr('onclick',methodToRun); // Enable the button's event before the click.
}
},
function(){
console.log('inactive'); // When you stop hovering over the button, it will log this.
$('#uniqueId').attr('onclick',null); // Disable the on click event.
});
});
What this does is it uses the hover event to trigger your checking logic and when the user finally clicks on the button, the button is enabled if the logic was correct, otherwise it does not do anything. Try it live on this fiddle.
P.S.: Convert $ to $j as necessary to adapt this.
P.S.2: Use the Javascript console to check how the fiddle works as it will not change anything on the page by itself.
Your problem is the submit event, just make :
$('form').on('submit', function(e) {
e.preventDefault();
});
and it works. Don't bind the button click, only the submit form. By this way, you prevent to submit the form and the button needs to be type button:
<button type="button" .....>Submit</button>
Assuming there's a form that is submitted when button is clicked.
Try adding
event.cancelBubble();
Hence your code becomes:
$j(document).on('click', '#uniqueId', function(event) {
// Don't propogate the event to the document
if (event.stopPropagation) {
event.stopPropagation(); // W3C model
} else {
event.cancelBubble = true; // IE model
}
if(condition == true) {
// continue...
} else {
return false;
}
return false;
});
Your code is mostly correct but you need to remove J:
$(document).on('click', '#uniqueId', function(event) {...
You also need to remove the onClick event from the inline code - there's no need to have it there when you're assigning it via jQuery.
<button id="uniqueId">Submit</button>

How can I set a value in a jquery dialog that is defined the first time the dialog closes?

I'm simply trying to find a way to create a confirm dialog in jquery to use in place of the default confirm function in javascript. I have a confirm dialog that's used to decide if I want to proceed without a given value in a form. The whole program is here:
http://nowlin.com/testpop.php
The button code that's giving me a headache looks like this, but it may not be the button code. I'm just learning jquery:
buttons: {
'Yes': function() {
document.getElementById("clicked").value = "true";
creturn = true;
$(this).dialog('close');
},
'No': function() {
document.getElementById("clicked").value = "false";
creturn = false;
$(this).dialog('close');
}
}
This program works fine except for the confirm dialog. I've tried setting a variable that has a global scope (creturn), and a DOM element from a hidden input (clicked.value), so that when the dialog closes I can tell which button was chosen. The values both get set, but not until after the form Send button, where the onclick event is located, is hit a second time:
<button type=submit name=clicked value=true onclick='return chkreq("cfbform")'>Send</button>
The behavior is, if you enter an email address and no name, and hit the Send button, the confirm dialog pops up. If you select Yes the dialog closes, but the form isn't submitted. If you click the Send button a second time, the dialog pops up again, immediately closes on its own, and the form is submitted. Clearly I'm missing something.
Thanks for any insights.
I would switch the button from type=submit to type=button (we can also drop the return)
<button type=button name=clicked value=true onclick='chkreq("cfbform")'>Send</button>
and then use jQuery to submit the form when it passed validation.
function chkreq(fid) {
// both values are set return true
if (document.getElementById(fid).elements.namedItem("name").value.length > 0 &&
document.getElementById(fid).elements.namedItem("email").value.length > 0) {
document.getElementById("clicked").value = "true";
$('#' + fid).submit();
}
...
}
And
buttons: {
'Yes': function() {
document.getElementById("clicked").value = "true";
$('#' + fid).submit();
$(this).dialog('close');
},
'No': function() {
document.getElementById("clicked").value = "false";
creturn = false;
$(this).dialog('close');
}
}
For more info see https://api.jquery.com/submit/
The other option used on that page is binding to the submit event. With your override-able validation via the popup, I think the above code will be easier to implement.
using Submit buttons and binding click events to them and handling the click in jQuery could cause issues like your jquery gets called then the post pack gets called because of the submit.
I suggest change the type of the button from "submit" to "button" and give it a try.

jQuery form submit: Any way to know what element triggered the submit?

I'm using asp.net MVC and when I submit a form, a previous developer had embedded some jQuery validation.
$('form').submit(function() {
...code done here to validate form fields
});
The problem is that both the "Save" and "Cancel" buttons on the form fire this submit jQuery function. I don't want the validation logic to fire if the "Cancel" input button was fired (id="cancel" name="cancel" value="cancel").
Is there a way that, within this submit function, I can retrieve the ID, name or value of which input button was pressed to submit the form?
I asked this same question: How can I get the button that caused the submit from the form submit event?
The only cross-browser solution I could come up with was this:
$(document).ready(function() {
$("form").submit(function() {
var val = $("input[type=submit][clicked=true]").val()
// DO WORK
});
$("form input[type=submit]").click(function() {
$("input[type=submit]", $(this).parents("form")).removeAttr("clicked");
$(this).attr("clicked", "true");
});
Not sure if its the answer you're looking for but you should change the "Cancel" button to an anchor tag. There's no need to submit a cancel unless you're doing work on the form values.
well this will only fire if the type of the input button is like so:
<input type='submit' ...
so make sure the cancel button does not have type='submit' and it should work
EDIT
This only works in FF and not in Chrome (and I so, I imagine, not in other WebKit based browsers either) so I'm just leaving this here as a browser specific workaround, an interesting note but not as the answer.
#Neal's suggestion of NOT making the cancel button of type submit is probably the cleanest way. However, if you MUST do it the way you are doing it now:
$('form').submit(function(e){
if(e.originalEvent.explicitOriginalTarget.id === 'cancel'){
//don't validate
}
else{
//validate
}
});
var myForm = $('form');
$('input[type="submit"]',myForm).click(function(e) {
var whoClickedsubmit = $(e.target); //further, you can use .attr('id')
//do other things here
});
EDIT
.submit(function(event){
var target = event.originalEvent.explicitOriginalTarget.value;
//But IE does not have the "explicitOriginalTarget" property
});

Categories