Consider following snippet:
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"></script>
</head>
<body>
<form>
<a id="a" href="http://google.com">Goooooogle</a>
</form>
<script>
$(function() {
var checkbox = $('<input type="checkbox"></input>');
checkbox.prependTo($('#a'));
checkbox.click(function(e) {
e.stopPropagation();
// do something useful
});
});
</script>
</body>
</html>
I want to get a checkbox inside <a>, and get following on-click behavior:
Toggle check mark normally as usual
Do something useful like AJAX-request
Stay on this page, i.e. not be redirected to an a href
Also I want to not override default behavior if I click anywhere in a, but not on checkbox. I.e. I want to allow to execute all event handlers associated with a click itself.
I thought that should be pretty easy, but I can't get desired behavior. Either:
I get redirected to Google if I put a code provided.
I don't get check mark toggled if I use e.preventDefault() of return false;. Furthermore in that case checkbox ignores explicit checkbox.attr('checked', 'checked') and all other possible ways to set the check mark.
Where is the catch?
UPD: This works as expected in Chrome, e.g. I'm not redirected on click, but fails in Firefox. Is there cross-browser way?
Well, it looks like a known Firefox bug, which leads to following link on checkbox click regardless of handlers' code. As a bit dirty workaround one can use:
var checkbox = $('<input type="checkbox"></input>');
checkbox.prependTo($('#a'));
checkbox.click(function(e) {
setTimeout(function() { checkbox.prop('checked', !checkbox.prop('checked')); }, 10);
// do something useful on clicking checkbox and but not surrounding link
return false;
});
I know this is an old question but some may still be curious since it was never really fully answered without a messy hack or workaround. All you have to do is simply check where the event's target originated.
So using your example (jsfiddle):
// Don't change pages if the user is just changing the checkbox
$("#a").click(function(e) {
//e.preventDefault(); // Optional if you want to to keep the link from working normally
alert("Click came from: " + e.target.tagName);
if (e.target.tagName != "INPUT") {
// do link
alert("Doing link functionality");
} else {
// do something useful
alert("Doing checkbox functionality");
}
});
I Know this question is over 5 years old, but I had the same issue recently and the work-around I found was to add an onclick function to the checkbox and in that function call event.stopImmediatePropagation().
from w3schools: "The stopImmediatePropagation() method prevents other listeners of the same event from being called"
ie...the anchor.
function checkbox_onclick(event){
event.stopImmediatePropagation();
}
here's a modified script
var checkbox = $('<input type="checkbox"></input>');
var a = $('#a');
a.unbind("click").click(function(e) {
e.preventDefault();
checkbox.attr('checked', !checkbox.attr('checked'));
});
checkbox.prependTo(a);
checkbox.click(function(e) {
e.stopPropagation();
// do something useful
});
i unbind the click event on the <a> and rebind it with a event to check/uncheck the checkbox and also prevent the default.
Related
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>
I've been working on trying to trigger an onchange listener with java script in Mozilla Firefox. I've found a lot on Stack Overflow posted about this, but nothing seems to be working for my unique case.
I've created this HTML with a onchange listener from an onchange event using this helpful post (JavaScript OnChange Listener position in HTML markup). Here's my code:
<HTML>
<head>
<script type="text/javascript">
window.onload= function () {
if(window.addEventListener) {
document.getElementsByClassName('search-box')[0].addEventListener('change', loadXMLDoc, false);
} else if (window.attachEvent){
document.getElementsByClassName('search-box')[0].attachEvent("onchange", loadXMLDoc);
}
function loadXMLDoc(){
alert('It worked');
}
}
function addTextCallListener() {
var searchBox = document.getElementsByClassName("search-box")[0];
searchBox.value = "Hello";
}
</script>
</head>
<BODY>
<input type="text" class="search-box" placeholder="Player Search">
<br \>
<button type="button" onclick="addTextCallListener()">Click Me!</button>
</BODY>
</HTML>
I also saved it as this jsfiddle (for some reason I had to keep it all together for it to work, I couldn't break it up into js and html).
https://jsfiddle.net/josephfedor42/crogL0zd/1/
If you play with this jsfiddle you can see that entering text and pressing enter will trigger the listener and the pop up with the message “It worked” will appear.
But if the button “Click Me!” is pressed it only changes the value of the text box, and the onchange listener is not called.
I realize I could easily add an onchange event to this button. But I want to to trigger the listener by programatically/ superficially using javascript in my addTextCallListener() function.
I've tried the simple stuff, like calling
searchBox.onchange();
searchBox.focus();
searchBox.click();
And a combination of these to add and remove the focus. But it doesn't seem to work. I've found quite a few posts on triggering an onchange event, but nothing that works in Firefox.
Any help would be appreciated.
Thanks for that link of a possible duplicated question. I had checked out that link before.
But I gave it a try again. I saved the jsfiddle from them both and neither one work.
My implementation of Dorian's answer
https://jsfiddle.net/josephfedor42/zaakd3dj/
My implementation of Alsciende's answer
https://jsfiddle.net/josephfedor42/xhs6L6u2/
emphasize mine
According to the mdn page about the change event,
The change event is fired for <input>, <select>, and <textarea>
elements when a change to the element's value is committed by the
user.
and to whatwg specs :
When the input and change events apply (which is the case for all
input controls other than buttons and those with the type attribute in
the Hidden state), the events are fired to indicate that the user has
interacted with the control.
Therefore, setting the value of an input is not an action "committed by the user" nor a sign that "the user has interacted with the control", since it was made by the code.
So, even if the specifications for this event are kind of unclear, the event should not fire when you change its value by code.
Something like this should work:
function addTextCallListener() {
var searchBox = document.getElementsByClassName("search-box")[0];
searchBox.value = "Hello";
//fire the event
if (document.createEvent) {
searchBox.dispatchEvent('change');
} else {
searchBox.fireEvent("onchange");
}
}
Here is the code I needed to add to my function addTextCallListener:
var evObj = document.createEvent('HTMLEvents');
evObj.initEvent( 'change', true, true );
searchBox.dispatchEvent(evObj);
I updated the jsfiddle. The working code is here https://jsfiddle.net/josephfedor42/crogL0zd/7/
Replace onchange with change in this part:
document.getElementsByClassName('search-box')[0].attachEvent("onchange", loadXMLDoc);
I have twp problems
Mark up for the link
DisplaySpreadsheetData
1)
Under document.ready i have this line of code to make sure the link is disabled by default but it does not work.
$('#displaySpreadSheetLink').bind('click', disableLink);
Code to disable the link
var disableLink = function (e) {
e.preventDefault();
return false;
}
2)
when the link is clicked i want to make sure that if checkFile() returns true the link should be disabled
$('#displaySpreadSheetLink').click(function (e) {
if (checkFile()) {
e.preventDefault();
}
});
There are two problems here. How can i correct the first problem and for the second one i think e.preventDefault() does not get executed even if checkFile() returns true.
Can anyone help please?
You might have an issue because you've actually bound two click events to your link. You should unbind the disableLink function before you bind the new functionality:
function disableLink(e) {
e.preventDefault();
// don't use return false here.
}
$(function() {
$('#displaySpreadSheetLink').click(disableLink);
});
// later on
$('#displaySpreadSheetLink').unbind('click').click(function (e) {
if (checkFile()) {
e.preventDefault();
}
});
Also, double-check your logic for checkFile(). Just based on the name I would assume, having never seen your code before, that you'd want to prevent the default behavior if checkFile() fails. Are you sure you don't want if (!checkFile()) { ... }?
Another approach might be to deal with only a single event, but take into account some extra state information as to whether the default behavior should execute or not:
(function($) {
var loaded = false;
$('#displaySpreadSheetLink').click(function(e) {
if (!loaded || checkFile()) {
e.preventDefault();
}
});
$(function() {
loaded = true;
});
})(jQuery);
Instead of disabling a link with a function after the page loads, you should change the HTML to be disabled initially by using a <span> with a CSS class that looks like a disabled link.
Instead of calling checkFile() every time the user clicks the link, have code in the sections that can alter whether checkFile() is true or false. For example, if checkFile() becomes true after a file is uploaded, put code in the file upload function to enable the link by replacing the <span> with an <a>, and link-disabling code in the appropriate places where checkFile() might become false again.
Merely using preventDefault() will make the link look clickable, which is probably bad UI design if it actually does nothing.
I have a list of radio buttons that I can toggle "yes" or "no" to using Javascript.
$(document).ready(function(){
$('#select-all').click(function(){
$('#notifications .notif-radio').each(function(){
$('input[type="radio"]', this).eq(0).attr('checked', true);
$('input[type="radio"]', this).eq(1).attr('checked', false);
});
});
$('#deselect-all').click(function(){
$('#notifications .notif-radio').each(function(){
$('input[type="radio"]', this).eq(0).attr('checked', false);
$('input[type="radio"]', this).eq(1).attr('checked', true);
});
});
});
this works just fine. Now I have a separate piece of code that detects when a user has changed something, and asks them if they want to leave the page.
var stay_on_page;
window.onbeforeunload = confirm_exit;
$('.container form input[TYPE="SUBMIT"]').click(function(){
stay_on_page = false;
});
$('#wrapper #content .container.edit-user form').change(function(){
stay_on_page = true;
});
function confirm_exit()
{
if(stay_on_page){ return "Are you sure you want to navigate away without saving changes?"; }
}
The problem is that if the user uses the first piece of functionality to toggle all radio buttons one way or another. The JS detecting form changes doesn't see that the form was changed. I have tried using .live, but to no avail. Anyone have any ideas?
I do something similar to this by adding change() (or whatever's appropriate, click() in your case I suppose) event handlers which set either a visible or hidden field value, then check that value as part of your onbeforeunload function.
So, my on before unload looks like:
window.onbeforeunload = function () {
if ($('#dirtymark').length) {
return "You have unsaved changes.";
}
};
And, or course, dirtymark is added to the page (a red asterisk near the Save button), when the page becomes dirty.
I just want to enable / disable onclick and href on elements (a or div).
I don't know how to do this.
I can disable onclick by adding an handler on click event, but the href is still available.
$(this).unbind().click(function(event){
event.preventDefault();
return;
});
Edit FOUND A HACK FOR A ELEMENTS
if ($(this).attr("href")) {
$(this).attr("x-href", $(this).attr("href"));
$(this).removeAttr("href");
}
If you return false on the onclick event, the href is irgnored.
This will go to Goole: <a
href="http://www.google.com"
onclick="alert('Go to
Google')">Test</a>
This will not go to Google: Test
Ok i've found a workaround : putting an overlay over the main div containing all the elements i wanted to disable ..
It just works.
You could try the following:
$('a, div').click(
function(e){
return false;
// cancels default action *and* stops propagation
// or e.preventDefault;
// cancels default action without stopping propagation
});
MDC documentation for preventDefault, jQuery documentation for event.preventDefault.
SO question: JavaScript event.preventDefault vs return false.
I'm unsure as to the problem of the "href still being available," since the click event is cancelled; however if you want to remove the href from a elements:
$('a[href]').attr('href','#');
will remove them (or, rather, replace the URL with a #).
Edited in response to comment (to question) by OP:
Ok, sorry ;) I just want to be able (by clicking on a button), to disable / enable all the links (click or href) over elements (div or a)
$('#buttonRemoveClickId, .buttonClassName').click(
function() {
$('a, div').unbind('click');
});
$('#buttonReplaceClickId, .buttonOtherClassName').click(
function() {
$('a, div').bind('click');
});
unbind(),
bind().
Try this to disable click:
$(this).unbind('click');
You can set the href attribute directly to "" to prevent the original from showing up in the status bar, if that's what you're asking.
$(this).unbind().click(function(event){
event.preventDefault();
}).attr("href", "");
Otherwise, a event.preventDefault() already stops links from being clickable.