tags:

views:

34

answers:

4

For a little bit of background, I have multiple checkboxes, each weighted with a different "score". When the checkbox is changed, I need to compute the score. I thought something like the following would work but it does not look like the .change event is being bound properly.

$(document).ready(function() {
   bindSomeCheckboxes();
});

function bindSomeCheckboxes() {
    var score=0;
    var checkboxes = {
        "id_1" : 3,
        "id_2" : 1,
        "id_3" : 2,
        "id_4" : 5
    };

    $.each(checkboxes, function(key, value) {
        $("#"+key).change(function(key,value) {
            if ($("#"+key).is(':checked')) {
                //add this ids value to score
            } else {
                //subtract value from score
            }
        });
    });
}  

I know that it is looping through the array correctly, but an alert in .change is never being seen.

A: 

try use 'bind' and ':checked'

$.each(checkboxes, function(key, value) {
    $(this).bind('change', function() {
      if ($(this).is(':checked')) {
        //do something when it is checked
      } else {
        //do something else
      }
    });
});
Floyd
In jQuery $(this).change(... is shorthand for $(this).bind("change", ...
Sohnee
A: 

I would recommend obtaining the checkboxes in a more natural way...

$("input[type='checkbox']").change(function () { 
    alert("Event is bound");
});

If you want to restrict which checkboxes to use, you could add a class, although if you can avoid adding unnecessary classes, your html will be cleaner.

Sohnee
+2  A: 

I recommend you to add a container and select all checkboxes at once.

And as for your question, the signature of the event is wrong, the correct is function(e){}. Also, you have to check if the element is checked, and not clicked.

$("#chk").change(function(e){
    if ($(this).is(":checked"))
        alert("checked");
    else
        alert("not checked");
});

To make it easier, use a container

Sample HTML

<div id="checks">
    <input type="checkbox" id="chk1" />
    <input type="checkbox" id="chk2" />
    <input type="checkbox" id="chk3" />
    <input type="checkbox" id="chk4" />
</div>

And for the scores, I prefer to set data on the elements, example:

$("#chk1").data("Score", 3);
$("#chk2").data("Score", 1);
$("#chk3").data("Score", 2);
$("#chk4").data("Score", 5);

$("#checks :checkbox").change(function(e){
    if ($(this).is(":checked"))
        alert("checked Score: " + $(this).data("Score"));
    else
        alert("not checked Score: " + $(this).data("Score"));
});
BrunoLM
I like this approach as well. Thanks for something different Bruno.
Magic Hat
+1  A: 

If you really wanted to take that approach of using IDs, I'd make a separate Array of the ID's, and do a .join() to create the selector.

Some things to note:

  • Instead of .is(':clicked') or .is(':checked'), use this.checked. Much more efficient.
  • Event handlers in jQuery have one parameter that refers to the event. You have 2 for key,value. This is making key in the handler refer to that event object instead of the key from the $.each().
  • Inside a handler, this refers to the one that was clicked.
  • Because you have this reference to the element, you don't need the reference to key in the $.each(). You can just do this.id.

function bindSomeCheckboxes() {
    var score=0;
    var checkboxes = {
        "id_1" : 3,
        "id_2" : 1,
        "id_3" : 2,
        "id_4" : 5
    };

    var arrayOfIds = []; // to store array of ids

    $.each(checkboxes,function(key, val) {  // populate array with ids
        arrayOfIds.push( key );
    });

       // create a selector of the IDs
    $( "#" + arrayOfIds.join(',#') ).change(function() {
          // alert the score
        alert( checkboxes[ this.id ] );
        if ( this.checked ) {
            //do something when it is checked
        } else {
            //do something else
        }
    });
} 
patrick dw
Thank you. This is what I was looking for. An explanation of my misunderstanding of what was going on and a possible solution. +1 :)
Magic Hat
@Magic - You're welcome. Let me know if you have any questions. :o)
patrick dw
Heh after all this I just realized that this isn't working partly because the div containing these checkboxes is not available on $(document).ready... Good times debugging the wrong things.
Magic Hat
@Magic - Ah yes, that would make a difference. :o)
patrick dw