Why can't this checkbox, created dynamically with jQuery, be clicked? - javascript

jsFiddle
I'm using a jQuery plugin that allows the user to draw boxes in an area. I use jQuery to put a checkbox (along with a dropdown list) in the box that appears when the user lets go of the mouse button (this is towards the bottom of the javascript in the jsFiddle). The problem is, the checkbox is unclickable.
I do have some click checking code in the _mouseStart, _mouseDrag and _mouseStop events to stop another box from being created when you click in an existing box, but I don't think this is causing the problem because the dropdown list that is created can be clicked, and furthermore if you remove the click checking code the checkbox remains unclickable.
What is causing the checkbox to be unclickable? Thanks for reading.
EDIT:
Thanks to VinayC's answer, I can now see that the click reaches the checkbox, with this code:
$('#box').click(function(e){
alert('clicked');
$(this).attr('checked', true);
});
But the $(this).attr('checked', true); line doesn't make the checkbox checked. Can anyone tell me why? I've updated the jsFiddle
EDIT 2:
Harmen noticed that the code assigns the same id to each checkbox. In the actual code there's a counter appended to the id, so each one is unique, but I've taken that out because I think this is just a jQuery issue. I'd change the jsFiddle, but if you just create one box (thus one checkbox), the same problem occurs.

I've got no idea why, but while fiddling around (yes, on fiddlejs), this seems to do the trick
$('#box', ui.box).click(
function(evt){
evt.stopPropagation();
}
);
when setting up the box. See: http://jsfiddle.net/BBh3r/9/
I was actually trying to intercept the event and manually set it checked, but if there's no need to set it then hey.. Perhaps there's an extra event generated somewhere negating the first..? Click's only triggered once though.
Might be related to building jquery checkbox - can't set checked value
PS. Only tested on Chrome for Linux

You're creating multiple checkboxes with the same id.

It appears that top level event handlers are cancelling the click event. Add onclick event handler on check-box element alerting and you will see that click reaches to the checkbox.

Actually it is checked while the alert is visible, but it becomes unchecked afterwards. I'm guessing that after your event handler sets it to checked, the default event for the click (which is to toggle the check mark) happens, and since it is checked at the moment, it becomes unchecked again. Try calling preventDefault from the click handler.

You can also try this for a more universal approach
This worked for me.
$(document).click(function (e) {
if (element.tagName == 'INPUT') {
if ($(element).attr("type") == 'checkbox') {
e.stopPropagation();
e.preventBubble();
return;
}
}
});

Related

How to Disable Click on a radio button without disabling it in JQuery?

Requirement :
I want to 'disable Click of a radio button' using JQuery. The radio button will be already checked, before click.
Conditions:
1) The disable attribute should not be set to true. Means we must not radio button to make click disable on it.
2) If user clicks on that radio button, then it should not get unchecked.
Why Such Requirement:
A Common JQuery is already written for onClick of all Radios in form. I want it not to get executed at all for particular radio.
As I do not have authority to change that jQuery. That JQuery enable disable some other elements on form on clicking of radio.
so i need to handle that in my Jquery either onload or some other method. I hope requirements are clear. Please help!!
Update:
From Answers i have created three fiddle but none worked yet.
1) https://jsfiddle.net/uhxpmexe/
2) https://jsfiddle.net/ry5zqcv7/
3) https://jsfiddle.net/k0gd57ks/
Looking, If someone can contribute more
I think you are asking "How can I remove an event handler from a specific radio button after some other code (which I don't have access to) adds the handler to all radio buttons in my form?"
If this is correct, you could simply give your radio an id and then call: $( "#myRadio").unbind( "click" );
You can simply return false in click handler:
$(":radio").click( function(){
return false;
});
Working Demo
Update: As you have already defined click handler, you need to unbind it and then add new click handler which returns false:
$("#ba").unbind('click').click( function(){
return false;
});
Working Demo
Just use event.preventDefault() jsfiddle
pointer-events: none; should do the trick. With addClass in jQuery you can add it any time
.disabled{
cursor: not-allowed; /* aesthetics */
pointer-events: none;
}
Also check out: https://css-tricks.com/almanac/properties/p/pointer-events/
you can use this code for disabled the radio button.
$(".example").attr('disabled','disabled');
Please let me know if code working for you.

Click event not always triggering

I'm using the bootstrap editor jquery plugin. I'm trying to set an event listener to the add hyperlink button, but it only gets triggered when the text input next to it is empty, otherwise it does not fire. Here's my jsfiddle. My code:
$('.dropdown-menu button').on('click', function () {
alert("ADD clicked");
});
To test the jsfiddle, simple select some text and press add without inputting a URL.
Then, select the text again, input a URL and press add, no alert() will be shown.
Any ideas why this is happening?
Something in this line is changing the behaviour for a reason I can't see right now:
$(this).parent('.dropdown-menu').siblings('.dropdown-toggle').dropdown('toggle');
If you remove it, seems work, so, something in dropdown (i guess) is doing something wrong for you

Blur event is fired on focused parent element if focused element's child is clicked

I need to create a part of a form where if you click on a select, a checkbox field should popup and if you click anywhere else again, this field should disappear. I would like to do this with focusing the field after clicking on the select, but for some reason, my checkbox field loses its focus not only when you click anywhere else out of it, but even when you click on a label of a checkbox INSIDE of it. So the problem is that I am focusing an element in which I click on a label and the focused parent element loses its focus for some reason I can not figure out.
The code: http://jsfiddle.net/RELuL/2/
Any helps appreciated!
P.S.:
Just some bonus question :) As you can see, if you click on the select input, my hidden checkbox section is displayed a little late, it is not shown instantly which looks a little bad. Any tips how to optimize this?
EDIT: I use Firefox 13.0.1
When you click on a <label>, the browser focuses the associated input field. So focus leaves the parent and goes to the checkbox (and your blur event handler is called).
Instead of focusing the parent div and relying on it being blurred, attached a click handler to the document:
$(document).click(function() {
multiSelectUpdate();
});
$('.multiselect.container').click(function(event) {
event.stopPropagation(); // prevent click event from reaching document
});
Also, in Webkit clicking on <select> doesn't fire a click event. A workaround is to use the focus event instead.
Demo
Ok two simple changes got this working first change the click listen on the select box to a mousedown listener like so.
$('.multiselector').mousedown(function(event) {
event.preventDefault();
currentMulti = $(this).attr('id');
thisOffset = $(this).offset();
$(this).hide();
$('#' + currentMulti + '-container')
.css('top', thisOffset.top + 'px').show().attr("tabindex", -1).focus();
$(this).addClass('active');
});
this triggers before the box is able to comes up so it never shows.
Secondly the blur listener was believing it lost focus when a child got focus to fix this change to focusout.
$('.multiselect.container').focusout(function() {
multiSelectUpdate();
});
This only fires when the selector loses focus even focus currently on child of selector.
Fixed fiddle
enjoy :)
EDIT
For some reason blur fires multiple times on FF so to work round this use instead of blur mouseleave.
$('.multiselect.container').mouseleave(function() {
multiSelectUpdate();
});

Checkbox not working before using script

I was asked to mark as checked the checkbox on the table line click, the script below is working but now when I click directly on the checkbox, it doesn't work, works only if I click the table line.
I have this html:
<tr class="linha_tela" id="4">
<td>Profile</td>
<td>Clientes</td>
<td>
<input type="checkbox" checked="checked" id="controller_4" name="controllers[]" value="4" />
</td>
</tr>
And this is my script:
$('.linha_tela').click(function(){
var checkbox = $(this).find(':checkbox');
checkbox.attr('checked', !checkbox.attr('checked'));
});
Thanks
What's happening is that the checkbox is toggling when you click on it, then the event handler is triggered causing it to become unchecked. This is basically occurring instantaneously, which is why it appears to just not work at all.
Try this:
$('.linha_tela').click(function(event) {
if (!$(event.target).is(':checkbox')) {
var checkbox = $(this).find(':checkbox');
checkbox.attr('checked', !checkbox.attr('checked'));
}
});
Edit: Here's a jsfiddle demo of it working.
This is happening because the checkbox is in the table row, so when you are clicking it, it's changing it's status (because that's what checkboxes do).
Then the click is bubbling up to your tr, and running the script, which is changing it status back.
you need to check the event target, and if it's not an input, do your thing, if it is, then don't.
here's the modified script:
$('.linha_tela').click(function(event) {
if (event.target.nodeName != 'INPUT') {
var checkbox = $(this).find(':checkbox');
checkbox.attr('checked', !checkbox.attr('checked'));
}
});
and a link to a jsfiddle to try it out:
http://jsfiddle.net/yDEyC/
$(":checkbox").click(function(event) {
event.stopPropagation();
});
This should work.
Here is a jsfiddle that demonstrates your code scenario:
http://jsfiddle.net/sAfTT/
The problem you're running into is a common one with events in HTML. When events are fired, they are fired on every element to which they can be applied in order from closest to furthest away. This is called bubbling(theres also capturing which works in reverse). http://www.quirksmode.org/js/events_order.html
So, in reality, when you are clicking on the checkbox, you are also clicking on the row, so the handler call looks like this.(assuming the box is unchecked to start with. reverse check/uncheck as applicable)
Checkbox clicked: check the box
Can I bubble up? Yes
Row clicked. Is there an event handler? Yes
Fire event handler (yours). This determines if the checkbox is checked. It is.
Because the box is checked, uncheck it.
Can I bubble up? Yes
Table Clicked. Is there an event handler? no
Document Clicked. Is there an event handler? No.
you can attach an event handler to the checkbox directly to prevent bubbling
$(':checkbox').click(function(e){
e.preventDefault();
e.stopPropagation();
})​
edit: I could never get the prevent default to work just right in jsfiddle, but the concept provided by the other answers work nicely too.

jQuery find(':focus') not acting as expected

I'm making a widget that slides in and out of view on hover with showTracker and hideTracker functions. I want to prevent it from sliding out of view if it contains a focussed form element though, so I've got this going:
function hideTracker(){
if($('#tracker').find(':focus').length == 0){
$('#tracker').stop().hide();
}
}
Cool. Now it doesn't hide if the mouse happens to move out if there's a field in focus. Unfortunately, that also means that when the field does lose focus (and it's time for the widget to hide again) it just stays there. The unHover event has been and gone.
So I added this:
$('#tracker *').blur(function(){
hideTracker();
});
And that works too - with one little bug that I need help with!
If the focus moves from one element within the tracker to another which is also within #tracker, the tracker hides. I figured that if($('#tracker').find(':focus').length == 0) would return false, given that the next form element has focus, but I guess it doesn't.
Is it the case that .blur() fires before the next element attains focus?
How can I get around this?
How about something like this?
$('body *').focus(function(){
if(!$(this).is('#tracker *') && $('#tracker:visible').length != 0) hideTracker();
});
Yikes. Tricky. Yes, what's happening is:
mousedown: old form element gets the blur event. $(':focus').length == 0.
mouseup: new form element gets the focus event. $newFormElement.is(':focus') == true.
This is an improvement:
$('#tracker').focusout(function() //basically like $('#tracker, #tracker *').blur(), but "this" is always '#tracker'
{
if(!$(this).is('#tracker:hover')) //for some reason plain old :hover doesn't work, at least on the latest OS X Chrome
hideTracker();
});
But it's not perfect. It only really works if you use the mouse. If you use tab to move between fields (or some other possible mechanism) while your mouse is not hovering over #tracker, it won't work.
Here's another attempt. It's a bit...hackier. The gist is that, instead of handling the blur event, you handle the focus event of the second thing that's focused. But! What if you click something that can't be focused? Blank space on your page? Then no focus event is fired.
Okay. So the trick is: put a tabindex="0" in your root <html> tag. This means that there is always something that can be focused. So there's no way to focus on nothing (at least, I don't think so).
Then you can do this:
$('*').live('focus', function(e)
{
if(!$.contains($('#tracker')[0], this)) //if the new thing you focused on is not a descendant of #tracker
hideTracker();
e.stopPropagation();
});
Eh? So yeah, that's a certified hack. But it's a tough problem, and that's the best I can come up with at this hour.
Thank you all for your answers. Utilising the .focus() event rather than .blur() was a clever way to look at it. Unfortunately, it does raise a couple of browser problems, and I couldn't get any of the above working very robustly.
In the end I decided to use setTimeout(hideTracker, 100); to allow the focus() event to take place before the count of focussed elements within tracker was evaluated. Not ideal, but it's working well and the delay is fairly imperceptible.
Thanks again.

Categories