views:

49

answers:

4

Hi

I have a ol list:

<ol>
<li class="group1">item 1</li>
<li class="group1">item 2</li>
<li class="group2"> item 3</li>
<li class="group3">item 4</li>
<li class="group1">item 5</li>
<li class="group3"> item 6</li>
<ol>

and a set of checkboxes which correspond to the class names

<input type="checkbox" value="group1" />group 1
<input type="checkbox" value="group2" />group 2
<input type="checkbox" value="group3" />group 3

What I want to happen is that when a user clicks on a checkbox to 'tick' it, any li rows which are not checked are fadedOut (change opacity) and then any rows which have the class which matches the value of the checkbox are highlighter (background colour changed to yellow).

So for example if group 3 was clicked, item 4 and item 6 would be highlighted. Then if group 2 was clicked item 3 would be highlighted (item 4 and 6 would remain highlighted). If group 2 was un-ticked, item 3 would become faded out although item 4 and 6 would remain highlighted.

The code I have at the moment is:

$('input').click(function(){
    input = $(this);
    classVal = "." + input.val();
    elements = $(classVal );

    if (input.is(':checked')) {
        elements.css("background-color", "#FFFF00");
    } else {
        elements.css("background-color", "");
    }
});

This handles the highlighting but does not do the fading of the unchecked elements. I know I can change the opacity using css("opacity", 0.33) or fadeTo("slow", 0.33) but not sure how to handle this in the code and where to put it.

If any of my other code can be tidied up also please let me know

Thanks

+1  A: 

Maybe I'm missing something, but why not just put it right after the line that changes the background color?

$('input').click(function(){
    input = $(this);
    classVal = "." + input.val();
    elements = $(classVal );

    if (input.is(':checked')) {
        elements.css("background-color", "#FFFF00");
        elements.fadeTo("slow", 1.0);
    } else {
        elements.css("background-color", "");
        elements.fadeTo("slow", 0.33);
    }
});
Syntactic
There's an issue with using fades, where its best to reset the animated style, and use .stop().. They do get stuck occasionally, especially where a user clicks on another trigger element while the animation is ongoing.
danp
You beat me to it, mine would accomplish the same thing.
bradenkeith
that will fade in / fade out that element. but the other elements in the list will be un-affected i.e not faded out. I want it so that only elements that have a class that matches one that have been ticked have the opacity set to 1. so what needs to happen is that the code goes through each element which does not have a class that has been selected and sets the opacity to 0.33.
John
@danp: I'll take your word for it. I have no idea how fades work in jQuery; I was just copying the line from the question.
Syntactic
@John: If I understand you correctly, this code (and bradenkeith's) will do what you want. You need only make sure that all of the elements' initial styles match their initial values. That is, any rows where the checkbox starts off checked need to start off with the highlighted style, and those that start off unchecked need to start off with the non-highlighted style.
Syntactic
+1  A: 
$('input').click(function(){
 input = $(this);
 classVal = "." + input.val();
 elements = $(classVal );

 if (input.is(':checked')) {
     elements.css("background-color", "#FFFF00");
     elements.css("opacity", 1);
 } else {
     elements.css("background-color", "");
     elements.css("opacity", 0.33);
 }
});

What about that? Just add another css attr to elements.

bradenkeith
that will fade in / fade out that element. but the other elements in the list will be un-affected i.e not faded out. I want it so that only elements that have a class that matches one that have been ticked have the opacity set to 1. so what needs to happen is that the code goes through each element which does not have a class that has been selected and sets the opacity to 0.33
John
I think this is correct, actually. Each time you click a checkbox, it'll fade in/out matching items. Each checkbox handles its own matching items - you don't need to recalculate all the other items when only one checkbox has changed state.
Matt Sach
+1  A: 

The jQuery code:

$('input:checkbox').bind('click', function(){
    var checkedClasses = $("input:checked").map(function() {
        return $(this).val();
    });
    var uncheckedOpacity = (checkedClasses.length == 0) ? 1.0 : 0.5;
    $('ol li').css({opacity: uncheckedOpacity, backgroundColor: 'transparent'});
    $.each(checkedClasses, function(index, value){
        $('.' + value).css({backgroundColor: '#ff0', opacity: 1.0});
    });
});

This HTML:

<ol>
    <li class="group1">item 1</li>
    <li class="group1">item 2</li>
    <li class="group2">item 3</li>
    <li class="group3">item 4</li>
    <li class="group1">item 5</li>
    <li class="group3">item 6</li>
<ol>

<form>
    <label><input type="checkbox" value="group1" />group 1</label>
    <label><input type="checkbox" value="group2" />group 2</label>
    <label><input type="checkbox" value="group3" />group 3</label>
</form>
artlung
what is the best way to set opacity back to 1 for all elements if none of the checkboxes are ticked?
John
I updated the code with that scenario
artlung
Thanks works GREAT!
John
A: 

Initially also you want the unselected li elements to be faded. For this purpose you need to use each() function. Please try the following. I have checked this code and it is working fine.

$('input').click(function() {

            $('input').each(function(index) {

                input = $(this);
                classVal = "." + input.val();
                elements = $(classVal);

                if (input.is(':checked')) {
                    elements.css("background-color", "#FFFF00");
                    elements.fadeTo("slow", 1.0);

                } else {
                    elements.css("background-color", "");
                    elements.fadeTo("slow", 0.33);
                }
            });
        });
mohang