All I find when I google this is the opposite.
I have this jquery for disabling form buttons after they were clicked once.
$('.btn').click(function (event) {
$(event.target).prop("disabled", true);
});
In Firefox (after adding autocomplete="off" because of this "feature") and IE this works as intended, the button is disabled but the form action is also performed, restricting the user form clicking it more than once. However in Chrome it stops the event propagation by itself, and I cannot find how to make it not do that.
You can force the form submission like that:
$(event.target).prop("disabled", true).closest("form").trigger("submit");
Related
I have a button as follows:
<input type="submit" class="button" value="FooBar" name="FooBar" id="FooBar" disabled="disabled">
I am enabling this button only when certain parameters are met. To test whether it was secure, I pressed F12 (or right click -> Inspect Element) and edited out the text disabled="disabled". Doing this overrides my code and that is scary. How can I prevent someone from changing it in this manner?
I am using php and jquery in this page and using the latter to enable or disable the button. I have checked the jquery click function and it not only executes, but shows the button as not disabled. The alert below reads Disabled: false
$("#FooBar").click(function(){
alert('Disabled: ' + $(this).is('[disabled=disabled]'));
})
So how can I prevent a user from changing the button disabled state and thus overriding my logic?
You can disable the right-click by doing:
document.addEventListener('contextmenu', event => event.preventDefault());
but it is not recommended. Why? It achieves nothing other than the annoying user
OR
Alternatively, a better approach is to recheck your validations in submit action and simply returns if it fails, in this case, if user inspects and changed the state of a button, the button stays idle and will not allow to proceed
$("#FooBar").click(function() {
if (!this.acceptenceCriteria()) {
return;
}
alert('Disabled: ' + $(this).is('[disabled=disabled]'));
})
You can't stop people from using dev tools.
You can try a couple of tricks to disable right clicking (like the one below) which will stop some number of people but ultimately the solution to your problem is to use html and http properly.
$(document).bind("contextmenu",function(e) {
e.preventDefault();
});
I quite understand that event.preventDefault() will prevent any default behavior triggered by an event on browser, but this definition is too broad for me, for example what are those event default behavior on browser? since it's quite common to find developers use event.preventDefault() but I still don't understand what kind of behavior they're trying to prevent.
If you click on a link, such as to http://example.com, your browser's default behavior will be to take you to http://example.com.
If you preventDefault in a click handler, the browser will no longer change your window location.
document.querySelector('.prevent-default').addEventListener('click', function (e) {
e.preventDefault();
}, false);
Normal Example
<a class="prevent-default" href="http://example.com">Prevented Example</a>
Other examples include:
submit has associated form submission
mousedown has associated text selection
keydown has associated input
touchstart may have associated scrolling/zooming behaviors.
one quick example is click event. Let's say you have a tag like
<a href="/my-sub-page.html" class='ajax-link'>
default behavior will be when you click this link it will take you to the /my-sub-page.html page. but if you want to avoid page refresh and instead you want to use ajax. then you will use
$('.ajax-link').on('click', function(event){
event.preventDefault();
$.ajax({
url : $(this).attr('href'),
success : function(response){
$('.my-content').html(response);
}
})
});
or another example can be form submits. Similar to above, you canprevent default behavior of form submission, and use ajax and get result from post request without loading the page.
There are many default browser actions:
mousedown – starts the selection (move the mouse to select).
click on <a href=""> - open the page.
click on <input type="checkbox"> – checks/unchecks the input.
submit – clicking an <input type="submit"> or hitting Enter inside a form field causes this event to happen, and the browser submits the form after it.
keydown – pressing a key may lead to adding a character into a field, or other actions.
contextmenu – the event happens on a right-click, the action is to show the browser context menu.
etc.
The event.preventDefault() method stops the default action of an element from happening.
For example:
Prevent a submit button from submitting a form
Prevent a link from following the URL
Use the event.isDefaultPrevented() method to check whether the preventDefault() method was called for the event.
So, I have a form with custom validation that is triggered on input blur event...
works fine
the form submit prevents the form to be submitted if there are validation errors on the page...
effectively what that means is if there is an erroneous message and it's focused.... if you click submit button, first the element's blur is triggered and the submit... but coz the element is
in practice I would have to click submit twice.... first time to re-validate the element and second to trigger submit again...(when all the elements are valid)
so on blur, I do
if ( event.relatedTarget && event.relatedTarget.type === "submit" ) {
...
}
and check if the instigator (of element's blur event) is the submit button...if yes, I skip the validation and trigger submit directly.... (that handles validation itself)..
It works perfectly, even in OSX...
the problem is mobile safari... that simply doesn't populate the event.relatedTarget... (is always null on submit click.... it's populated only on some other element's focus)....
how can I get the instigator on iOS?
I had the same problem where I had to hit the submit button on my form twice (on iOS.) Surprisingly I found that this solution worked:
how to prevent blur running
It was not clear at first but using this solution the mousedown event stops my normal blur event from happening but if you click the "Done" on the iOS keyboard it will let the blur event run because there was no mousedown event.
I am using the keyup event to fire the same event as clicking on the search button when a user presses the return key. When the search button is clicked it uses an Ajax request to load search results on the page.
The call works fine, but the keyup event is being captured when I press the return button in the address bar in google chrome after previously having focus on the input box, e.g. if the user types in a search query without pressing return, and instead goes to a new webpage using the Google Chrome address bar, when they press return on the address bar the search in my page is being submitted at the same time as the keyup event is being trigger even though the page, and certainly the input box, should no longer have focus.
JavaScript
$("#search-box").on("keyup", function(event) {
if(event.keyCode == 13){
$("#search-submit-btn").click();
}
});
HTML
<div class="input-append"/>
<input id="search-box" type="text" />
<button class="btn" id="search-submit-btn">Search</button>
</div>
I'm also using Twitter bootstrap to style the Input box, but I don't think this is causing the problem.
I've tested this page in Firefox and Safari without any issue. Does Google Chrome have a problem with the keyup event/is this a know issue? I'm struggling to find any information on the issue.
EDIT
I think I've solved my issue by using keydown instead of keyup. I've also added in a check if the element is still focused, but I don't think this makes a difference, since it still has the same affect with keyup.
$("#search-box").on("keydown", function(event) {
if($("#search-box").is(":focus")){
if(event.keyCode == 13){
$("#search-submit-btn").click();
}
}
});
This appears to be an okay solution for me, but it doesn't explain why keyup behaves so strangely in Google Chrome though. If anyone has anymore information about why keyup is this way in Google Chrome or if I am just doing something wrong, I'd be very interested to hear.
I have an <input type=text> with focusout event handler
I have a <button> with click event handler
Focusout checks whether format in input box is correct. It does so by testing input value against a regular expression. If it fails it displays a message (a div fades-in and -out after some time) and refocuses my input by calling
window.setTimout(function() { $(this).focus(); }, 10);
since I can't refocus in focusout event handler. focusout event can't be cancelled either. Just FYI.
Click collects data from input elements and sends it using Ajax.
The problem
When user TABs their way through the form everything is fine. When a certain input box failes formatting check it gets refocused immediately after user presses TAB.
But when user doesn't use TAB but instead clicks on each individual input field everything works fine until they click the button. focusout fires and sets time-out for refocusing. Since time-out is so short focusing happens afterwards and then click event fires and issues an Ajax request.
Question
I have implemented my formatting check as an independent jQuery plugin that I want to keep that way. It uses .live() to attach focusout on all input fields with a particular attribute where format regular expression is defined.
Data submission is also generic and I don't want to make it dependant on formatting plugin. They should both stay independent.
How can I prevent click event from executing without making these two plugins dependant?
Example code I'm fiddling with
After some searching I've seen that all major browser support document.activeElement but I can't make it work in Chrome. FF and IE both report this being the active element, but Chrome always says it's BODY that is active even though click fired on the button element.
Check this code http://jsfiddle.net/Anp4b/1/ and click on the button. Test with Chrome and some other browser and see the difference.
You could use a flag...
Live demo: http://jsfiddle.net/Anp4b/4/
So your question is:
How can I prevent click event from executing without making these two plugins dependent?
Well, you obviously cannot prevent the click event. If the user wants to click the button, he will, and the click event will trigger. There's nothing you can do about that.
So the answer to the above question is: You cannot.
Based on the current conditions, you have to - inside the click handler - retrieve the validation result, and based on that result, decide if form submission should or should not occur.
JS Code:
$("#Name").focusout(function(){
var that = this;
valid = this.value.length ? true : false;
!valid && window.setTimeout(function() {
$(that).focus();
}, 0);
});
$("#Confirm").click(function(e) {
if ( !valid ) { return false; }
e.preventDefault();
alert('AJAX-TIME :)');
});
HTML Code:
<input type="text" id="Name">
<button id="Confirm">OK</button>
Is there are reason you use .focusout instead of .blur?
Using a flag is a good idea, but I would rather use a class on the element. By using classes to determine the state you can also style it accordingly. Here's my example based on your fiddle.
Another solution that hopefully gives the result you are looking for.
1) Create a named click handler:
var clickHandler = function(e){ /** submit form or whatever you want to do**/ };
$("button").click(clickHandler);
2) Add the following to the focusout event when it's failing validation:
$("button").unbind("click", clickHandler).one("click", function(){ button.click(clickHandler); return false;});
You can find an example of this here.