I have a kendo grid with its dataSource, the grid has an editor dialogue with save button. I need to prevent the save button being double clicked. The onsave functions fire when the save button is clicked. I have a requestEnd event that fires when the save is to be re-enabled.
The problem: onSave1 looks to fail 1 time in 100 . It's based on adding an additional click handler, invoking preventDefault(). Is it fundamentally flawed?
Is onSave2 any better?
onSave1: function (e) {
$(event.srcElement)
.addClass("k-state-disabled")
.bind("click", disable = function (e) { e.preventDefault(); return false; })
this.dataSource.one("requestEnd", function () {
$("[data-role=window] .k-grid-update")
.off("click", disable)
.removeClass("k-state-disabled");
})
}
onSave2: function (e) {
$(event.srcElement)
.removeClass(".k-grid-update")
.addClass("k-state-disabled")
.addClass("disabledMarker");
this.dataSource.one("requestEnd", function () {
$("[data-role=window] .disabledMarker")
.addClass(".k-grid-update")
.removeClass("k-state-disabled")
.removeClass("disabledMarker");
})
}
First Jquery bind has been deprecated since version 3.0 so I would recommend not using it anymore. http://api.jquery.com/bind/
You do not need an onClick event or in your case bind because onSave is already being called during the click. So simply disable the button onSave. Second you should use complete or whatever kendo grid uses for when the save event is finished instead or requestEnd. Code listed below.
onSave: {$(event.srcElement)addClass("k-state-disabled")}, complete:{ $(event.srcElement)removeClass("k-state-disabled")};
I am using jquery validation for everything I'm about to talk below.
so I have an input field, lets call it email. I also have a submit button for this form. Now by default the error message for email field will not kick in until I hit the submit button. Then whenever I type it will show/hide error message dependant on if it is a valid email. This check happens with every key stroke and this is a very important distinction to make so that you would understand my problem I posted below.
Now I have a background colour on the input, it is suppose to be green when validation has passed and red when it has failed. I have this part working, let me show you how I did it:
window.onload = function () {
$(".js-validate-circle").on("input", function () {
UpdateValidationCircle(this);
});
}
function UpdateValidationCircle(e) {
if ($(e).valid()) {
$(e).parent().addClass("active");
} else {
$(e).parent().removeClass("active");
}
}
The active class is what determines if its green or red. There is styling that is irrelevant I think to the question so I wont post it here.
Here is my problem: When the page loads and I start typing, it forces validation to trigger and error messages start coming in before I click the submit button for the first time. I am trying to prevent this. I want the color the start changing on typing only after the submit button was hit. Functionality of my red/green background should match jquery validation messages.
How would I accomplish something like this? I tried using on change but then the validation triggers only when the box loses focus.
jQuery(function($) { // DOM ready and $ alias in scope
// Cache elements
var $circle = $(".js-validate-circle");
var addedInputEvent = false; // Just a flag to know if we already added the evt listener
// On form submit....
$("#form").on("submit", function(event) {
// Prevent default form submit
event.preventDefault();
// Check immediately
$circle.each(UpdateValidationCircle);
// If not already assigned, assign an "input" listener
if(!addedInputEvent) {
addedInputEvent = true;
$circle.on("input", UpdateValidationCircle);
}
});
function UpdateValidationCircle() {
var $el = $(this);
$el.parent().toggleClass("active", $el.valid());
}
});
Use the keyup event instead:
$(".js-validate-circle").on("keyup", function () {
...
Assuming .js-validate-circle is your input... or if it is the form:
$(".js-validate-circle").on("keyup", "#id-of-the-input", function () {
...
If this doesn't work, we are going to need to see validate()s code and some markup.
I have following jQuery code to prevent double clicking a button. It works fine. I am using Page_ClientValidate() to ensure that the double click is prevented only if the page is valid. [If there are validation errors the flag should not be set as there is no postback to server started]
Is there a better method to prevent the second click on the button before the page loads back?
Can we set the flag isOperationInProgress = yesIndicator only if the page is causing a postback to server? Is there a suitable event for it that will be called before the user can click on the button for the second time?
Note: I am looking for a solution that won't require any new API
Note: This question is not a duplicate. Here I am trying to avoid the use of Page_ClientValidate(). Also I am looking for an event where I can move the code so that I need not use Page_ClientValidate()
Note: No ajax involved in my scenario. The ASP.Net form will be submitted to server synchronously. The button click event in javascript is only for preventing double click. The form submission is synchronous using ASP.Net.
Present Code
$(document).ready(function () {
var noIndicator = 'No';
var yesIndicator = 'Yes';
var isOperationInProgress = 'No';
$('.applicationButton').click(function (e) {
// Prevent button from double click
var isPageValid = Page_ClientValidate();
if (isPageValid) {
if (isOperationInProgress == noIndicator) {
isOperationInProgress = yesIndicator;
} else {
e.preventDefault();
}
}
});
});
References:
Validator causes improper behavior for double click check
Whether to use Page_IsValid or Page_ClientValidate() (for Client Side Events)
Note by #Peter Ivan in the above references:
calling Page_ClientValidate() repeatedly may cause the page to be too obtrusive (multiple alerts etc.).
I found this solution that is simple and worked for me:
<form ...>
<input ...>
<button ... onclick="this.disabled=true;this.value='Submitting...'; this.form.submit();">
</form>
This solution was found in:
Original solution
JS provides an easy solution by using the event properties:
$('selector').click(function(event) {
if(!event.detail || event.detail == 1){//activate on first click only to avoid hiding again on multiple clicks
// code here. // It will execute only once on multiple clicks
}
});
disable the button on click, enable it after the operation completes
$(document).ready(function () {
$("#btn").on("click", function() {
$(this).attr("disabled", "disabled");
doWork(); //this method contains your logic
});
});
function doWork() {
alert("doing work");
//actually this function will do something and when processing is done the button is enabled by removing the 'disabled' attribute
//I use setTimeout so you can see the button can only be clicked once, and can't be clicked again while work is being done
setTimeout('$("#btn").removeAttr("disabled")', 1500);
}
working example
I modified the solution by #Kalyani and so far it's been working beautifully!
$('selector').click(function(event) {
if(!event.detail || event.detail == 1){ return true; }
else { return false; }
});
Disable pointer events in the first line of your callback, and then resume them on the last line.
element.on('click', function() {
element.css('pointer-events', 'none');
//do all of your stuff
element.css('pointer-events', 'auto');
};
After hours of searching i fixed it in this way:
old_timestamp = null;
$('#productivity_table').on('click', function(event) {
// code executed at first load
// not working if you press too many clicks, it waits 1 second
if(old_timestamp == null || old_timestamp + 1000 < event.timeStamp)
{
// write the code / slide / fade / whatever
old_timestamp = event.timeStamp;
}
});
you can use jQuery's [one][1] :
.one( events [, data ], handler ) Returns: jQuery
Description: Attach a handler to an event for the elements. The handler is executed at most once per element per event type.
see examples:
using jQuery: https://codepen.io/loicjaouen/pen/RwweLVx
// add an even listener that will run only once
$("#click_here_button").one("click", once_callback);
using count,
clickcount++;
if (clickcount == 1) {}
After coming back again clickcount set to zero.
May be this will help and give the desired functionality :
$('#disable').on('click', function(){
$('#disable').attr("disabled", true);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="disable">Disable Me!</button>
<p>Hello</p>
We can use on and off click for preventing Multiple clicks. i tried it to my application and it's working as expected.
$(document).ready(function () {
$("#disable").on('click', function () {
$(this).off('click');
// enter code here
});
})
This should work for you:
$(document).ready(function () {
$('.applicationButton').click(function (e) {
var btn = $(this),
isPageValid = Page_ClientValidate(); // cache state of page validation
if (!isPageValid) {
// page isn't valid, block form submission
e.preventDefault();
}
// disable the button only if the page is valid.
// when the postback returns, the button will be re-enabled by default
btn.prop('disabled', isPageValid);
return isPageValid;
});
});
Please note that you should also take steps server-side to prevent double-posts as not every visitor to your site will be polite enough to visit it with a browser (let alone a JavaScript-enabled browser).
The absolute best way I've found is to immediately disable the button when clicked:
$('#myButton').click(function() {
$('#myButton').prop('disabled', true);
});
And re-enable it when needed, for example:
validation failed
error while processing the form data by the server, then after an error response using jQuery
Another way to avoid a quick double-click is to use the native JavaScript function ondblclick, but in this case it doesn't work if the submit form works through jQuery.
One way you do this is set a counter and if number exceeds the certain number return false.
easy as this.
var mybutton_counter=0;
$("#mybutton").on('click', function(e){
if (mybutton_counter>0){return false;} //you can set the number to any
//your call
mybutton_counter++; //incremental
});
make sure, if statement is on top of your call.
If you are doing a full round-trip post-back, you can just make the button disappear. If there are validation errors, the button will be visible again upon reload of the page.
First set add a style to your button:
<h:commandButton id="SaveBtn" value="Save"
styleClass="hideOnClick"
actionListener="#{someBean.saveAction()}"/>
Then make it hide when clicked.
$(document).ready(function() {
$(".hideOnClick").click(function(e) {
$(e.toElement).hide();
});
});
Just copy paste this code in your script and edit #button1 with your button id and it will resolve your issue.
<script type="text/javascript">
$(document).ready(function(){
$("#button1").submit(function() {
$(this).submit(function() {
return false;
});
return true;
});
});
</script
Plain JavaScript:
Set an attribute to the element being interacted
Remove the attribute after a timeout
If the element has the attribute, do nothing
const throttleInput = document.querySelector('button');
throttleInput.onclick = function() {
if (!throttleInput.hasAttribute('data-prevent-double-click')) {
throttleInput.setAttribute('data-prevent-double-click', true);
throttleInput.setAttribute('disabled', true);
document.body.append("Foo!");
}
setTimeout(function() {
throttleInput.removeAttribute('disabled');
throttleInput.removeAttribute('data-prevent-double-click');
}, 3000);
}
<button>Click to add "Foo"!</button>
We also set the button to .disabled=true. I added the HTML Command input with type hidden to identify if the transaction has been added by the Computer Server to the Database.
Example HTML and PHP Commands:
<button onclick="myAddFunction(<?php echo $value['patient_id'];?>)" id="addButtonId">ADD</button>
<input type="hidden" id="hasPatientInListParam" value="<?php echo $hasPatientInListParamValue;?>">
Example Javascript Command:
function myAddFunction(patientId) {
document.getElementById("addButtonId").disabled=true;
var hasPatientInList = document.getElementById("hasPatientInListParam").value;
if (hasPatientInList) {
alert("Only one (1) patient in each List.");
return;
}
window.location.href = "webAddress/addTransaction/"+patientId; //reloads page
}
After reloading the page, the computer auto-sets the button to .disabled=false. At present, these actions prevent the multiple clicks problem in our case.
I hope these help you too.
Thank you.
One way I found that works is using bootstrap css to display a modal window with a spinner on it. This way nothing in the background can be clicked. Just need to make sure that you hide the modal window again after your long process completes.
so I found a simple solution, hope this helps.
all I had to do was create a counter = 0, and make the function that runs when clicked only runnable if the counter is = 0, when someone clicks the function the first line in the function sets counter = 1 and this will prevent the user from running the function multiple times when the function is done the last line of the code inside the function sets counter to 0 again
you could use a structure like this, it will execute just once:
document.getElementById('buttonID').addEventListener('click', () => {
...Do things...
},{once:true});
I have a confirm box on my colorbox("are you sure you want to leave?").
This triggers when i close the popup. This works when i click on the "cboxClose" div on the popup.
I am trying to show this confirm box on a button click. But the popup just closes right away without showing the confirm box.
My question is how do i trigger the the confirm box when i click on a cancel button. i tried several ways
//This just closes the pop up without showing the confirm box
$('#btnCancel').click(function () {
parent.$.colorbox.close(); });
//doesn't work
$('#btnCancel').click(function () {
$('#cboxClose').click()
});
COLORBOX
onComplete: function () {
$("#cboxClose").click(function (e) {
// stop any other script from firing
e.stopPropagation();
if (confirm('are you sure you want to leave?')) {
$.colorbox.close();
// ensure that the binding is removed when closed
$("#cboxClose").unbind();
}
});
} // close oncomplete
The issue here is that colorbox registers a click handler on the cboxClose element. As a result, neither stopping bubbling nor preventing the click (by returning false in a click handler) will have any effect because the colorbox handler is already registered. The only way of stopping that handler from being run is to unbind it. However, to do that you need a reference to the handler, which you won't get without modifying the colorbox code.
In any case, that's what's going on and why the code you have above doesn't work. Another option for you would be to override the colorbox close function (which is the public colorbox method that is called by colorbox's close button handler). All you need is this:
$.colorbox._close = $.colorbox.close;
$.colorbox.close = function() {
if(confirm("Close?")) {
$.colorbox._close();
}
}
The down side (which may not be an issue in your situation) is that this will affect all colorboxes on the page.
I solved this issue by making this method and binding it to the cancel button
var originalClose = $.colorbox.close;
$.colorbox.close = function (e) {
var response;
var formChanged = localStorage.getItem("isFormChanged");
var saveClicked = localStorage.getItem("saveClicked");
if (formChanged == "true" && saveClicked == "false") {
response = confirm('Do you want to close this window? All your changes will not be saved');
if (!response) {
return
}
}
originalClose();
};
<input type="button" value="Cancel" id="btncancel" onclick="parent.$.colorbox.close()"/>
I'm using buttons to submit data via Ajax. I'm using jQuery to disable and enable the buttons. This is to prevent "button-mashing," where a user can fire multiple requests either maliciously or unwittingly.
Is there an "element-agnostic" way to prevent this behavior in jQuery? For example, say I wanted to use anchors instead of buttons to submit the data. A button I can disable; but as far as I know you can not disable anchors.
Here is how I'm doing this now: (note I've removed some of the unnecessary code to make it shorter)
$('.fav .button').click(function() {
$.ajax({
context: this,
dataType: 'json',
beforeSend: function() {
// Toggle state; disable button to prevent button mashing
$(".fav").toggleClass("fav-state-1");
$(".fav .button").attr("disabled", true);
},
error: function() {
// Rollback state and re-enable button on error
$(".fav").toggleClass("fav-state-1");
$(".fav .button").attr("disabled", false);
},
success: function(response) {
if (response.result == "success") {
$(".fav .button").attr("disabled", false);
}
else {
// Rollback state; re-enable button
$(".fav").toggleClass("fav-state-1");
$(".fav .button").attr("disabled", false);
}
}
});
return false;
});
HTML:
<input class="button" type="button" value="">
Of course, the best way to do this would be to handle it gracefully on the server side.
That said, you could use the data storage methods in jQuery to store a value to indicate it has already been clicked, and use that to determine if the user has already clicked/pressed the button. The values get stored per selector, so you can set it on anything.
$("a").click(function(e) {
e.preventDefault();
if (!$(this).data('isClicked')) {
var link = $(this);
// Your code on successful click
// Set the isClicked value and set a timer to reset in 3s
link.data('isClicked', true);
setTimeout(function() {
link.removeData('isClicked')
}, 3000);
} else {
// Anything you want to say 'Bad user!'
}
});
The benefit is that you're not stopping the user from clicking anything else, as it's a per element solution. In your case, you might want to do the link.removeData in the success function.
Example of it working: http://jsfiddle.net/jonathon/ke8Az/ (Note that if you try to click again within the 3s, you get the 'Please wait' but you can still click the rest)
Note: This is a client side solution only. And only if they have JavaScript installed. Unless you handle it on the server side, the user can maliciously send multiple requests. This just helps with the 'unwittingly' part.
Before the ajax call you could unbind the click event on the clicked object, then in the success / error method you could rebind the click event.
That way they can mash the button as much as they want but it wont have the click wired up until the call has finished.
You could do the following:
setup a variable clickedWithinLastSecond.
in the method that fires the request, check if it is true, if it is then don't send the request
If it is not send the request and set the variable to true. Setup a method that fires after a second with setTimeout that changes the variable back to false.
you will have to customize variable name to your needs, and you will need to find a way to keep the variable in the correct scopes, but that is not difficult.
The best and only way to stop the behavior you are describing is on the server side.
You can also use debounce to register only one click. Both underscore.js and lodash.js provide this handy method.
Here's a fiddle to demo the concept. With lazyClick, you can double/triple click on the link yet the event handler is fired only once.
var lazyClick = _.debounce(onclickHandler, 500);
function onclickHandler(e){
e.preventDefault();
console.log('clicked');
}
$(function(){
// uncomment this and you will see double clicks are being registered.
//$('#btn').click(onclickHandler);
// with debounce, only one click will be registered
$('#btn').click(lazyClick);
});