Question

I am using playing around with the Pretty-checkboxes-plugin and have a problem. The plugin can be seen here http://aaronweyenberg.com/90/pretty-checkboxes-with-jquery

As you can see, this uses two links to select and deselect. I want it to only use one link and then change the class to make it work the other way the next time it is clicked.

It should be simple enough. I have been trying to get it working with toggleClass.

I simply put in the toggleClass statement so the code looks like so:

$(document).ready(function() {

/* see if anything is previously checked and reflect that in the view*/
$(".checklist input:checked").parent().addClass("selected");

/* handle the user selections */
$(".checklist .checkbox-select").click(
function(event) {
  event.preventDefault();
  $(this).parent().addClass("selected");
  $(this).parent().find(":checkbox").attr("checked","checked");
  $(this).toggleClass("checkbox-select checkbox-deselect");

 }

);

$(".checklist .checkbox-deselect").click(
 function(event) {
  event.preventDefault();
   $(this).parent().removeClass("selected");
   $(this).parent().find(":checkbox").removeAttr("checked");
   $(this).toggleClass("checkbox-select checkbox-deselect");
   }

   );

});

This works to some extend. The classes toggle just fine, but the rest of the code only works the first time it is run. All subsequent clicks just toggle the class og the link and nothing else.

Does anyone have any idea why this is?

Was it helpful?

Solution

$(this).toggleClass("checkbox-select checkbox-deselect");

Just changing an element's class doesn't change the event listeners registered on it. You registered the handler for selecting on elements matching $(".checklist .checkbox-select") at ready-time and that handler, not the deselecting handler, is still in place after the element has changed from .checkbox-select to checkbox-deselect.

If you really want event-time binding, you need the live() function instead of plain click() binding. However, I suggest you'd probably be better off with a single function:

$('#checktoggler').click(function() {
    // select all, unless all are already selected, in which case select none
    var selected= $('.checklist input:checked').length!==0;
    selected= !selected;

    $(this).parent().toggleClass('selected', selected);
    $(this).parent().find(":checkbox").attr('checked', selected);
    $(this).toggleClass('checkbox-select checkbox-deselect', selected);
});

OTHER TIPS

The way you've set up your event handlers makes me think that you are imagining that the handlers will be invoked based on the "class" setup dynamically. What you've actually got there is something that statically binds handlers based on the class setting at the time that the "ready" handler is called. The changing of the class assignment does nothing to the way that those handlers are invoked.

Instead of that setup, there are a couple of ways to go. First, you could bind a single event handler and then check the current class inside that handler with a simple "hasClass()" test. That would be pretty simple.

Another approach would be to use the "delegate" or "live" mechanisms, which really do have the dynamic interpretation behavior that your current code seems to wish for.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top