1

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/

1
  • Edited my answer with a big update. Take a look please. Commented Dec 14, 2011 at 6:29

3 Answers 3

2

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.

Sign up to request clarification or add additional context in comments.

5 Comments

cool! That fixes the checkbox problem, but it still displays the wrong data. Notice how "red square" comes back even though we unchecked squares.
That is because of the way you select $targets. You are selecting all LI elements that have "red" in them. So, it catches LI class="red square". When you call var $targets = $itemsToFilter.children("li." + $this.val()); $this.is(":checked") ? $targets.show() : $targets.hide(); -- you are showing all LI elements that have "red" in the class. This is why it shows red square.
I see what you are saying. Looks like this is what I need to do. //I need to Go thru targets and then ADD CODE to remove targets that have unchecked children var $targets = $itemsToFilter.children("li." + $this.val()); $this.is(":checked") ? $targets.show() : $targets.hide();
You should use prop('checked') instead of is().
@lolwut - he is using jQuery 1.6.4 which does not support prop
1

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();
    }
});

Comments

0

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.