Pass Ctrl + Click Event to another element in Firefox - javascript

It's come to my understanding that Firefox will not pass Ctrl + Click from label, to target input field. I'm at a loss as to how I can achieve this behaviour. I have checkbox fields, which are hidden, and their respective labels that are styled uniquely and visible... When clicking the label, click registers, but control click does not.

I assume html as
<form>
<label for="home" id="lblhome">home</label>
<input type="checkbox" name="home" id="home"><br>
</form>
I want one thing if ctrl+cliked other thing if it's just click , the checkbox click code
$( "#home" ).click( function( e) {
if(e.ctrlKey)
alert('i just got ctrl+cliked');
else
alert('i just got clicked');
});
So now create handler for label check if it's ctrl+click if yes then create an jquery Event and change its ctrlKey property to true and trigger it on the checkbox.
$('#lblhome').click(
function(e){
if(e.ctrlKey) {
alert('ctrl+click on label');
//cancel the normal click
e.preventDefault();
e.stopPropagation();
e2 = jQuery.Event("click");
//e2.which = 50; // for other key combos like CTRL+A+click
e2.ctrlKey = true;
$( "#home").triggerHandler(e2);
$( "#home").prop("checked", !$( "#home").prop("checked"));//toggle checkbox state
}
});
DEMO : https://jsfiddle.net/35g41aaL/

This is kind of hacky, but it works: http://jsbin.com/dogelehena/edit?html,console,output
<input type="checkbox" id="cb">
<label for="cb">Label</label>
<script>
$(function () {
var cb = $('#cb');
var isFirefox = navigator.userAgent.toLowerCase().indexOf('firefox') > -1;
$('label').click(function (e) {
if (e.ctrlKey && isFirefox) {
var checked = cb.prop('checked');
cb.prop('checked', !checked);
}
});
});
</script>
First, attaching the click event to the label and not the input. This way, the event is not blocked when ctrl is held down, but the checkbox state does not change. So in the callback, we check for e.ctrlKey, and if it's true, we change that checkbox's state manually.
Please note that I added the isFirefox check, because while this functionality fixes the behavior in Firefox, it breaks in other browsers.

Related

Button with focus - run function on 'Enter'

I have my code below. It's doing what I want. What I want to also do is run this function when a user use their keyboard to tab to the .add-row button and then presses enter. How do I make that run?
$('body').on('click', '.add-row', function(e) {
$( this ).html('Hide').removeClass('add-row').addClass('hide-row');
$( this ).parent().parent().next().show();
});
My understanding is you want the button to have focus and the user to press enter to fire the event, yeah? If so, then using the :focus pseudo class selector on the .add-row should work with the keypress event
$("body").on("keypress", ".add-row:focus", function(e) {
var ENTER_KEY_CODE = 13;
if (e.keyCode === ENTER_KEY_CODE)
{
alert("Enter key pressed");
// perform hide row and other operations here
}
});

Event handling issue with label and input inside it [duplicate]

window.onload = function(){
var wow = document.getElementById("wow");
wow.onclick = function(){
alert("hi");
}
}
<label id="wow"><input type="checkbox" name="checkbox" value="value">Text</label>
This is my code, when I clicked on "Text" it will alert hi twice but when I clicked on the box, the onclick element will only trigger once, why?
When you click on the label, it triggers the click handler, and you get an alert.
But clicking on a label also automatically sends a click event to the associated input element, so this is treated as a click on the checkbox. Then event bubbling causes that click event to be triggered on the containing element, which is the label, so your handler is run again.
If you change your HTML to this, you won't get the double alert:
<input id="wowcb" type="checkbox" name="checkbox" value="value">
<label id="wow" for="wowcb">Text</label>
The label is now associated with the checkbox using the for attribute instead of wrapping around it.
DEMO
If your intention is to respond only to clicks on the label and not on the checkbox, you can look at the event.target property. It references the element that called the listener so that if the click wasn't on that element, don't to the action:
window.onload = function(){
var el = document.getElementById('wow');
el.addEventListener('click', function(event) {
if (this === event.target) {
/* click was on label */
alert('click was on label');
} else {
/* click was on checkbox */
event.stopPropagation();
return false;
}
}, false);
}
If, on the other hand, you want to only respond to clicks on the checkbox (where a click on the label also produces a click on the checkbox), then do the reverse. Do nothing for clicks on the label and let ones from the checkbox through:
window.onload = function(){
var el = document.getElementById('foolabel');
el.addEventListener('click', function(event) {
if (this === event.target) {
/* click was on label */
event.stopPropagation();
return false;
} else {
/*
** click is from checkbox, initiated by click on label
** or checkbox
*/
alert('click from checkbox');
}
}, false);
}
This version seems to have the most natural behaviour. However, changing the markup so that the label no longer wraps the checkbox will mean the listener is not called.
Event bubble.
The checkbox is the child node of the label. You click the checkbox. Event bubble to the label. Then alert pop up twice.
To prevent alert pop up twice when you click the checkbox. You can change you onclick function into this:
wow.onclick = function(e){
alert('hi');
stopBubble(e);
}
function stopBubble(e)
{
if (e && e.stopPropagation)
e.stopPropagation()
else
window.event.cancelBubble=true
}
Hope this can work for you.
The Label tag will be associated with the input tag inside it. So when you click the label, it will also trigger a click event for the input, then bubble to the label itself.
See this:
document.getElementById("winput").addEventListener('click', function(event){
alert('input click');
//stop bubble
event.stopPropagation();
}, false);
http://jsfiddle.net/96vPP/
Rammed headfirst into this gotcha again and decided to prove what it did to myself, hopefully helping me remember. To help future people to whom the above might not be clear enough, here the example I made.
https://jsfiddle.net/ashes/0bcauenm/
$(".someBigContainer").on("click", "input[type=checkbox]", ()=> {
$output.val("Clicked: checkbox\n" + $output.val());
});
edit: added the link with a snipped of the code.
This is probably the simplest answer. Just add a span around your text and stop event propagation.
window.onload = function(){
var wow = document.getElementById("wow");
wow.onclick = function(){
alert("hi");
}
}
<label id="wow">
<input type="checkbox" name="checkbox" value="value">
<span onclick="event.stopPropagation()">Text</span>
</label>
Or without inline-javaScript
window.onload = function(){
var wow = document.getElementById("wow");
wow.onclick = function(){
alert("hi");
}
var span = document.getElementsByTagName("span")[0];
span.onclick = function(event){
event.stopPropagation();
}
}
<label id="wow">
<input type="checkbox" name="checkbox" value="value">
<span>Text</span>
</label>
For those using React and Material UI - I've encountered this issue on one of my forms. event.preventDefault() is stopping the event from bubbling as described by the accepted answer.
<Button
onClick={(event) => {
event.preventDefault()
this.handleCardClick(planName)
}}
>
<FormControl component="fieldset">
<RadioGroup
row
value={selectedPlan}
>
<FormControlLabel
control={<Radio color="secondary" />}
label={label}
/>
</RadioGroup>
</FormControl>
</Button>
Use change to listen for events instead of click

How to change the value of HTML input of type checkbox on mouse down event

What would be the best way to accomplish this? This should also (naturally) disable the default on mouse up event, which by default will change the value of the checkbox.
HTML:
<input type="checkbox" name="mycheckbox" value="checkme" />
JavaScript:
var checkbox = document.getElementsByName("mycheckbox")[0];
checkbox.addEventListener("mousedown", function(e){
if(!e){ e = window.event; }
//Stop checkbox from being toggled on IE9 & Other Browsers
if(e.stopPropagation){ e.stopPropagation(); }
//Stop checkbox from being toggled on IE8 and Lower
else{ e.cancelBubble = true; }
//Toggle the checkbox yourself instead
checkbox.checked = (checkbox.checked) ? true : false;
//And you can also change the value of the checkbox
checkbox.value="newvalue";
});
How about setting a click function on the checkbox
$(document).on('click', '#myCheckBoc', function(e){
e.preventDefault();
alert($(this).val()); //initial value
$(this).val('15');
alert($(this).val()); //changed value
});
FIDDLE
With some assumptions, I have come up with this working code snippet:
Let me know if you need something else.
document.getElementById("checkboxValue").innerHTML = document.getElementById("checkbox").value;
document.getElementById("checkbox").onmousedown = function(e){
e.preventDefault();
alert("Changing checkbox value...");
this.value = "value2";
document.getElementById("checkboxValue").innerHTML = "value2";
};
<input type="checkbox" id="checkbox" value="value1" />
<p>Checkbox Value: <span id="checkboxValue"></span></p>
checkbox.onclick = (e) => e.preventDefault(); // disable built-in behaviour
checkbox.onmousedown = (e) => {
checkbox.checked = !checkbox.checked;
// if you need it to still fire 'change' event:
checkbox.dispatchEvent(new Event('change'));
}
Other answers either disabled wrong event (e.preventDefault() should be called on click, not on mousedown) either missed the mousedown part.

Disable opposite input if I type into another of a pair

How do I disable one input field if I type into another out of a pair and then if I removed the input by hitting backspace for example so there is nothing in the input field reenable the second input field and vice versa. Code I have so far is below but is not working.
JavaScript:
//disable the opposite input field
var ATGvalue = $('input#atgOrderId').val();
var BQvalue = $('input#bqOrderId').val();
if ( ATGvalue.length > 0) {
$('input#bqOrderId').prop("disabled", true);
} else {
$('input#bqOrderId').removeAttr("disabled");
}
if ( BQvalue.length > 0) {
$('input#atgOrderId').prop("disabled", true);
} else {
$('input#atgOrderId').removeAttr("disabled");
}
HTML:
<label for="bqOrderId">bqOrderId </label><input name="bqOrderId" id="bqOrderId" type="text" />
<label for="atgOrderId">atgOrderId </label><input name="atgOrderId" id="atgOrderId" type="text" />
Your code does work, but only once - to have it continuously update, you first wrap the JS in an event-handler function and attach it to your input elements:
function mutuallyExclusive( e ) { ... }
$( '#bqOrderId' ).on( 'change keyup', mutuallyExclusive );
$( '#atgOrderId' ).on( 'change keyup', mutuallyExclusive );
See this JSFiddle.
I attached it to both the change and keyup events: change to handle programatic (scripted) changes, and keyup to "instantly" update the fields' statuses - otherwise it waits till the user removes focus from the input to call the change event.
you need to include your code inside an event to check when a user type something like this:
$(document).on('keyup','#bqOrderId',function(){
//your code
});
$(document).on('keyup','#atgOrderId',function(){
//your code
});
after to change this:
$('input#bqOrderId').prop("disabled", true);
$('input#atgOrderId').prop("disabled", true);
to this:
$('input#bqOrderId').attr("disabled",true);
$('input#atgOrderId').attr("disabled", true);

How do you propagate a click to child elements if the parent element has preventDefault?

UPDATE:
this doesn't work in the latest version of firefox (15.0.1):
http://jsfiddle.net/DerNalia/NdrNV/5/
clicking the checkbox navigates to google... but it shouldn't :(
it appears that adding e.stopPropagation() doesn't help / doesn't work.
playarea: http://jsfiddle.net/DerNalia/NdrNV/1/
What I'm trying to do:
When I click the checkbox that is next to (but actually is a child element of) the anchor, it should change states, and also change the state of the "other" checkbox.
But because the anchor has e.preventDefault() invoked, the checkbox never gets checked.
Here is my markup
Link Name <input class="home" type="checkbox"/>
<br />
Sync'd checkbox: <input class="other" type="checkbox" />​
Here is some the troubled jquery
$(function() {
$("input.home").click(function() {
$("input.other").click();
});
$("a").click(function(e) {
e.preventDefault();
// prevent default so we can do some ajaxy things instead of follow the href
});
})​
So, how do I change the jQuery click action on the anchor tag such that clicks propagate to child elements (but I can still do ajaxy things without the browser following the href of the anchor tag)?
Is there a way to do this without changing the markup? (the way it is now makes semantic sense for my web application)
It doesn't work because event.preventDefault would cancel the event.
Using e.preventDefault on click on the checkbox which is wrapped inside <a> would not let you change the checkbox state.
A workaround I could think of is to set the checkbox state in a different context so that the e.preventDefault code is ineffective.
DEMO: http://jsfiddle.net/NdrNV/10/
$(function() {
$("input.home").click(function() {
$("input.other").click();
});
$("a").click(function(e) {
e.preventDefault();
var setCheckbox = function() {
var checkbox = $(e.target)[0];
checkbox.checked = checkbox.checked?false:true;
}
if ($(e.target).is(':checkbox')) {
setTimeout(setCheckbox, 0);
}
});
})
Note: This is a workaround.
You can put condition e.target.tagName like this,
if(e.target.tagName == 'A')
e.preventDefault();
Live Demo
$(function() {
$("input.home").click(function() {
$("input.other").click();
});
$("a").click(function(e) {
if(e.target.tagName == 'A')
e.preventDefault();
// prevent default so we can do some ajaxy things instead of follow the href
});
})​
$(function() {
$("input.home").click(function() {
if($(this).attr('checked') == 'checked')
$(this).removeAttr('checked');
else
$(this).attr('checked', 'checked');
$("input.other").click();
});
$("a").click(function(e) {
e.preventDefault();
// prevent default so we can do some ajaxy things instead of follow the href
var target = e.target; // object that triggers the event
$(target).children().trigger('click');
});
});

Categories

Resources