Preventing double-click bug with checkbox + label combination - javascript

Note this issue may not apply to the general public, as it does not occur unless you're a fast clicker. (150-200ms/click) The reason I'm posting this issue is because my application has a form with 20+ checkboxes next to each other, and after extensive research I've found no related questions on this matter.
Here's a simplified scenario - 4 checkboxes and 4 labels, one for each checkbox id:
[CB1] Label 1
[CB2] Label 2
[CB3] Label 3
[CB4] Label 4
Assume in each case all CBs are unchecked.
Expected Behavior:
I click on the 4 CBs in rapid succession, they will all become checked. (true)
I click on the 4 Labels in rapid succession, and the corresponding CBs become checked. (only true for Chrome, but still not optimal)
Actual Behavior for case 2 on Win 7 (clicking on labels, because as you know, labels are big and style-able, and the checkboxes are tiny and OS-dependent):
(In Firefox 19) CB2 and CB4 are left unchecked, and while going down the list the word "Label" gets highlighted for Label 2 and Label 4, as if I double-clicked on them.
(In Chrome 26) All CBs get correctly checked, but while going down the list the word "Label" gets highlighted for Label 2 and Label 4, as if I double-clicked on them.
(In IE 10) CB2 and CB4 are left unchecked, but no false highlighting.
The erroneous behavior could be justified if the clicks are on the same element. In our case those are clearly unique checkboxes with different IDs and Names. So the results are wildly unexpected.
So my question is:
Is there a way to disable firing the double click event when I rapidly click on the different checkboxes, but yet still check them with fast single clicks?
The closest I've come to is the following script, which interestingly made Firefox behave like Chrome, and Chrome behave like Firefox:
jQuery(document).on('dblclick', 'input:checkbox+label', function(event){
console.log('ugly hack fired');
$(this).click();
event.preventDefault();
})

Finally got one very ugly hack that worked for all the browsers, hopefully this will help anyone else who comes across the problem:
Disable selection with css because doing it in JS is simply too inefficient:
.form_class input[type=checkbox] + label{
-webkit-user-select:none;
-khtml-user-select:none;
-moz-user-select:none;
-o-user-select:none;
user-select:none;
}
Prevent ALL clicking in JS, and manually do what clicking should do:
jQuery(document).on('click', '.form_class input:checkbox+label', function(event){
// Assuming label comes after checkbox
$(this).prev('input').prop("checked", function(i, val){
return !val;
});
event.preventDefault();
})

This would do it-
$("input[type='checkbox']").dblclick(function (event)
{
event.preventDefault();
});

Try this:
$(document).on('dblclick', 'input:checkbox, label', function (event) {
event.preventDefault();
// Your code goes here
})
OR
$("input:checkbox, label").dblclick(function (event) {
event.preventDefault();
// Your code goes here
});
OR
$('input:checkbox').add('label').dblclick(function (event) {
event.preventDefault();
// Your code goes here
});

I was also facing a similar issue which had me spend whole night on how this can be fixed for checkbox. I was also listening to the 'dblclick' event to prevent any action from happening on double click on a checkbox.
ex:
#(".some_class").on("dblclick",function(event){
event.preventDefault();
});
But the problem here was that it was firing the event after the action was done. So all the damage was already done.
There is a very simple way to tackle this problem that is by listening for the event 'change' instead of listening to 'click'. In this was we are triggering the event when there is a state change from check to unchecked or from unchecked to checked and not on click or double click.
#(".some_class").on("change",function(event){
event.preventDefault();
});

$('.checkbox_class').click(function(event){
if (event.ctrlKey){ event.preventDefault();
//rest of the code
seems to work

Related

How to stop my code putting tabs into my text boxes

I have this piece of jQuery to detect when the cursor is inside the text box. The idea is to highlight the table row that the text box appears is.
$(".text").on("focus", function() { //do something });
The problem is that this code seems to be registering the tab key inside the text box. The cursor will still move to the next text box when I hit the tab key. However it always insert a tab space into the box as well!!
This is most unexpected and I must admit i'm a little confused by it...
Any help on this matter would be brilliant, thank you.
It seems that the alert() you are sending in the focus event is interrupting things in a strange way. You can fix this by setting a brief timeout before sending the alert; that ensures that the alert is sent AFTER the text box receives focus and the tab input has been handled.
setTimeout(function() { alert("box selected"); }, 1);
http://jsfiddle.net/5cjbcy9o/2/
Give every row a tabindex like this
var i=2;
$('tr').each($(this).attr('tabindex',i++))
A previous answer has addressed listening to the tab key, by checking the keyCode to see if it matches 9. However, the width of a tab character differs (also reliant on personal preferences), although it is either two or four spaces commonly. Therefore, you can append that white space to the value of the input text when the tab keydown event is detected.
In the following code I have opted to use four white spaces:
$(function () {
$(".text").on("focus", function () {
console.log("box selected");
}).on("keydown", function(e) {
if ((e.keyCode || e.which) == 9) {
e.preventDefault();
$(this).val($(this).val() + " ");
}
});
});
See proof-of-concept fiddle here: http://jsfiddle.net/teddyrised/5cjbcy9o/1/

Trigger event on a select when the value is the same

I am triggering a event when the user changes a selection in a select menu. As you would imagine it works when the user selects a option that is different than what is already there but when it is the same nothing happens. I have tried changing it to a click event but that doesnt seen to work.
If anyone has a work around for this it could greatly be appreciated.
I have found some solutions to this issue but none of them seem to work for me.
I am also using backbone if this makes a difference to you
My event looks like this:
'change .js-select' : 'show_colours',
UPDATE:
Thanks for the feedback
My scenario is this.
I have four select menus with 0, 1 and 2 as the options. If the user selects anything but zero a block of colour tiles will appear below it so the user can click on a colour. This is the same for all of the select menus.
Now due to lack of space the user can only have one block of colours open at a time. So if the user wants to go back and change a colour on a closed block of colours they need to select a different option than what they already have because if they select the same the event to open the block of colours will not fire.
I hope that is clear.
You can try something like this:
var open = false;
$('select').on('mouseup', function () {
if (open) alert(this.value);
open = !open;
});
http://fiddle.jshell.net/6LYbu/1/
Update
Since this will not work on touchdevices, we should listen for the change-event too:
var open = false;
$('select').on('mouseup change', function (e) {
if (open || e.type === 'change') alert(this.value);
open = !open;
});

jQuery .click function executes twice in a row

I'm working on my first program using jQuery, but I'm having an issue. I have a dialog pop up on pageLoad that asks the user to select a date and a turn. Right now, for debugging purposes, I have it alert every time .click() executes, and for some reason, it seems like it executes before the user clicks and immediately afterward.
There are three radio buttons, Turns 1, 2, and 3. When the user clicks Turn 1, the alert should say "1". When the user clicks Turn 2, the alert should say "2", etc. But for some reason, it alerts the previous value as well as the new one. I searched all of my code, and there is only one alert, so I can't figure out what is calling click() twice. I've tested it in IE and Chrome and it happened both times.
This is my .click() function:
$("#turn-radio")
.click(function () {
turnvalue = $("input[name='turn-radio']:checked").val();
alert(turnvalue);
});
If you check this jsfiddle, you'll see the rest of my code, which will hopefully make it easier to figure out what my problem is.
Thanks!
You need to change selector: as your radio button IDs are different and you were giving name as a selector that's why you were facing that problem:
$("input[name='turn-radio']")
.click(function () {
turnvalue = $("input[name='turn-radio']:checked").val();
alert(turnvalue);
});
Updated Fiddle
changing
$("#turn-radio") to $("#turn-radio label")
causes only one popup displaying the previous value
But, personally i would
$("#turn-radio input").change( function() { /* do stuff */ } )

How can I put a button in the down state?

Suppose I have a button, which goes into a down state when someone clicks on it, but before the mouse is released.
Now suppose instead that someone presses the 'a' key, I want the button to go into the down state, until the key is released, at which point it is triggered. Is this possible?
After dooing some research here is the final answer I got:
You can trigger mousedown or mouseup events on a button element using keyup and keydown
if your button is programmed to change its style according to these events than you are good to go.
See this fiddle example: http://jsfiddle.net/FwKEQ/15/
Note that if you use jQuery's UI components than it does work. But for standard buttons there is no way that you can move them to their pressed state using javascript
html:
<button id="jQbutton">Press 'A' to move me to pressed state</button>
Javascript:
<script>
$( "#jQbutton" ).button();
$(document).keydown(function(event) {
if ((event.keyCode === 97)||(event.keyCode === 65))
$("#jQbutton").mousedown();
});
$(document).keyup(function(event) {
if ((event.keyCode === 97)||(event.keyCode === 65))
$("#jQbutton").mouseup();
});
</script>
EDIT:
There might be a hack that we could utilize:
using accesskey for the button element and then try to simulate the accesskey press (that i am not sure if possible)
here is where i'm at so far http://jsfiddle.net/FwKEQ/28/
EDIT 2:
So looking further into this topic i have found the following:
Default buttons (without styles) are rendered by the OS, I was not able to find a formal proof for that but if you try to load the same page using a mac OS you'll get mac OS style buttons while in windows you will get the "ugly" gray button.
Because the default buttons are rendered by the OS they comply to OS events meaning events that are sent by the browser and are trusted.
this is not true for custom styled buttons as they comply to CSS an JS to change their appearance on press that is why the JQ button is affected by JS.
so to summarize you would need a trusted press event to fire on a default button to change its style and that cannot be done due to security constraints.
read a bit more about trusted events here: http://www.w3.org/TR/DOM-Level-3-Events/#trusted-events
and if someone could find a formal reference with regards to the default buttons being rendered by the OS please comment or edit this answer.
Unfortunately the rendering of the active state on default buttons neither
is a simple matter of css styling nor can be easily changed by applying
javascript.
An option to do this on default buttons is to use the hotkeys jquery plugin: https://github.com/jeresig/jquery.hotkeys or implement alternative key codes for different browsers.
and to apply 50% opacity to the default button when pressed (to indicate the keydown).
(To me it seems almost perfect ;-) It probably is as good as it can easily get to work across platforms and browsers using default buttons.
jsfiddle DEMO
and the code ...
html:
<button id="test">Test Button</button>
Selected: <span class="selected" id="out"></span>
javascript:
$('#test').click(function () {
fn_up();
});
fn_down = function(event){
$('#test').css("opacity", 0.5);
$('#test').focus();
event.preventDefault();
}
fn_up = function(event){
$('#test').css("opacity", 1);
$('#out').append(" test");
event.preventDefault();
}
//to bind the event to the 'a' key
$(document).bind('keydown','a', fn_down);
$(document).bind('keyup','a', fn_up);
//to get the same effect with the 'space' key
$(document).bind('keydown','space', fn);
$(document).bind('keyup','space', fn2);
In the fiddle I apply it to the space button and the mousedown/up to achieve the same effect with all events (but you could just use it with the 'a' key ... this is a matter of taste).
Here is a jsfiddel that shows how it's done using jQuery: http://jsfiddle.net/KHhvm/2/
The important part:
$("#textInput").keydown(function(event) {
var charCodeFor_a = 65;
if ( event.which == charCodeFor_a ) {
// "click" on the button
$('#button').mousedown();
// make the button look "clicked"
$('#button').addClass('fakeButtonDown');
// do some stuff here...
// release the button later using $('#button').mousedown();
}
});
The button event is triggered when entering "a" in the input field. But as Mark pointed out you need to fake the styling for the clicked button because the browser doesn't do it.
Edit: I'm not sure if you're using jQuery in your project. I just wanted to show that it is possible at all. If it can be done with the jQuery library there is also a way to do it in pure javascript. ;)

IE 6 & IE 7 printing radio buttons

I have a "calculator" which has two radio buttons (link to form) you select before you perform the calculation.
To see my issue, you select the radio button marked "N-12" [to test, we just put "5" in "Slope" and "30" in "Pipe Size" and select "N-12", then calculate], then perform the calculation everything is fine until you print.
Because people want to have a paper copy of the calculation, they often print the calculated form after it's completed but if you've selected "N-12" and printed the page, it will print with the "Single Wall" radio button selected.
I've read that this is a bug and that you can force IE8 to recognize the checked radio button with JS, which is what I did, but it's not working for IE6 & 7.
This is the JS that I used to correct this problem for IE8:
function toggleRadioCheckbox(el) {
if ( el.getAttribute('checked') != 'checked' ) {
el.setAttribute('checked','checked');
}
else {
el.removeAttribute("checked");
}
}
Does anyone know what I need to do to correct this for IE6 and 7.
Yes. Try this (requires jQuery) solution:
// We want the change event to trigger when the radio buttons are clicked.
// Normally IE doesn't
// trigger change until the radio button has lost focus.
// Fake it with this click handler
$('input:radio').click(function() {
this.blur();
this.focus();
});

Categories

Resources