user584583
user584583

Reputation: 1280

my jquery checkbox bug

I can't figure out a good way to fix this bug. If I uncheck square, uncheck red, then recheck red, the red square comes back. How can I make sure I don't add any of the unchecked shapes back when the user unchecks and checks a color?

My real work example has more checkboxes and 100 times more data. JSFiddle clearly shows the bug.

thanks!

http://jsfiddle.net/h3AbN/

Upvotes: 1

Views: 107

Answers (3)

mrtsherman
mrtsherman

Reputation: 39872

This one was driving my bonkers. It seems like such a straightforward problem, but I couldn't come up with a super straightforward solution. Anyways, take a look and see if this works for you. I think it is simpler than your current code, although at first glance you may not think so. It has the added benefit of being able to support multiple properties. So for example, if you added a third filter item, like hasBorder then it would continue to work.

  1. Monitor change event of checkboxes
  2. If checkbox is unchecked, then just hide everything that has that class
  3. If checkbox is checked then we need to start showing stuff.
  4. Get all list items that have this class
  5. Filter out any list items for which a checkbox is unchecked.

http://jsfiddle.net/mgaRw/10/

$('input').change( function() {
    var value = $(this).val(); 
    //checkbox is checked
    if ($(this).is(':checked')) {
        var targets = $('.filterThis li')
             //filter on class
            .filter( function() {
                if ($(this).hasClass(value)) return true;
            })
             //filter on other checkbox states
            .filter( function() {
                var classList = $(this).attr('class').split(/\s+/);
                var index = classList.indexOf(value);            
                if (index !== -1) {
                    classList.splice(index, 1);
                }
                var include = true;
                $.each(classList, function(index, item){
                    if ($('input[value="'+item+'"]').not(':checked').length) {
                        include = false;
                        return false;  
                    }
                });

                return include;
        });

        //show list items
        targets.show();
    }
    else {           
        //hide list items
        $('.filterThis li').filter( function() {
            if ($(this).hasClass(value)) return true;
        }).hide();
    }
});

Upvotes: 1

PapaSmurf
PapaSmurf

Reputation: 1035

Thought I'd give it a go, I came up with a new version here that works: http://jsfiddle.net/kwBTg/1/.

Upvotes: 0

danludwig
danludwig

Reputation: 47375

Found it. It was with this line:

$.each($tmp, function(i, val4) {
    if ($this.is(":checked")) { // problem is here
        if ($('.' + val4 + '').is(":visible") == true) {

Change to this

$.each($tmp, function(i, val4) {
    if ($(this).is(":checked")) { // problem is here
        if ($('.' + val4 + '').is(":visible") == true) {

Update: Why?

You were confusing $this and $(this). You define $this early in your function, and it points to the checkbox the user clicked. However, in your $.each function, you want to check whether the checkbox in checkArray was checked. To do this, you should reference the item in checkArray, not the checkbox that was clicked.

Upvotes: 2

Related Questions