开发者

Custom styled checkboxes - problem with my JavaScript logic (an else branch is not getting hit)

I'm creating some custom "checkboxes" and what I mean by that is I'm just stylizing label elements and will be positioning the checkbox off the screen. This is the design/functionality that came in, so I figured I'd give it a go using semantic checkboxes.

What I want is when you click one of these custom "checkboxes" (you're really triggering the stylized label), the "checkbox" should change color and the background div behind all the "checkboxes" should "light up" as well. I've got all that working.

When you uncheck the "checkboxes", that "checkbox" would unhighlight but you should still get the background div color while you have any "checkboxes" checked. When you uncheck that final "checkbox", it should unhighlight and turn off that background div color. This is where I'm having problems.

Best illustrated with an example!

http://jsfiddle.net/xS2JU/

I've got console.log statements and if you watch them, you'll see I'm not executing that 3rd branch when you turn off the last checkbox. I'm just keeping track of th开发者_JAVA技巧e checked state and using a simple counter to keep track of how many "checkboxes" are checked. Anyone have any ideas?


Live Demo

Since this is only doing it onchange count would always be at LEAST 1, so it was never at 0 thus the 3rd branch was never called. Or a better explanation, if one was unchecked it HAD to be checked prior, making count start at 1 on the last call. I just moved your condition inside of the 2nd condition because this is where you uncheck, at that point you see if they all are unchecked.

$(function() {
    var $help_choices    = $('#help_choices'),
        count            = 0;

        console.log(count);

    $('input:checkbox', $help_choices).change(function() {
        var checked    = this.checked,
            $label    = $(this).parent();
        if (checked) { //additive checkboxes, check one or multiples
            $help_choices.addClass('help_choices_selected');
            $label.addClass('help_label_selected');
            count++;
            console.log(checked + '  ' + count);
        } else { //subtractive checkboxes, uncheck one or multiples
            count--;
            $label.removeClass('help_label_selected');

           // Put the final check here 
           if(count === 0){
                 $help_choices.removeClass('help_choices_selected');
                $label.removeClass('help_label_selected');
                console.log(checked + '  ' + count + ' 3rd branch');
            }
        }
    });

});

Also heres a bit shorter code where you dont have to keep track of count, could be optimized further, but basically I just check if any inputs are checked within the parent by getting the length of the input:checked on the #help_choices element.

Demo 2

$(function() {
    var $help_choices    = $('#help_choices');        

    $('input:checkbox', $help_choices).change(function() {
        var checked    = this.checked,
            $label    = $(this).parent();

        if (checked) { //additive checkboxes, check one or multiples
            $help_choices.addClass('help_choices_selected');
            $label.addClass('help_label_selected');
        } else{ //subtractive checkboxes, uncheck one or multiples
            $label.removeClass('help_label_selected');

            if($('#help_choices input:checked').length === 0){
                $help_choices.removeClass('help_choices_selected');
            }
        }
    });
});


The problem is that when there is exactly one checkbox checked and you uncheck it, it will go down the second branch because count > 0 (until you decrement it inside that branch), and thus you'll never enter the last branch. Also, you don't really need to test count >=0 in the first if because (once you get the code working) count will always be >=0.

Remove the else from the third branch and just make it an if inside the second branch.

if (checked) { //additive checkboxes, check one or multiples
  $help_choices.addClass('help_choices_selected');
  $label.addClass('help_label_selected');
  count++;
} else if (!checked && count > 0) { //subtractive checkboxes, uncheck one or multiples
  count--;
  $label.removeClass('help_label_selected');
  if (count == 0)  { //now no checkboxes selected
    $help_choices.removeClass('help_choices_selected');
  }
}


Instead of incrementing and decrementing the count variable inside the if/else conditions. Do it as a first thing in the change event handler. It makes your logic very simple.

if(checked)
    count++;
else
    count--;

Working demo

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜