tags:

views:

582

answers:

4

Hello,

I am validating some check boxes and would like for the user to be able to select only 4 (from 7 possible) and disable the others if the current box is being checked(if there are already 3 checked) or enable the everything if the current box is being unchecked. I'm really not sure where's the problem. This is my first experience with JavaScript...

function verify_selected(selected_check_box_id) {
 var count = 0;
 var selected_check_boxes = new Array();
 var check_boxes = new Array();
 var inputs = document.getElementsByTagName("input");
 for( var i in inputs ) {
  if( inputs[i].type == "checkbox" ) check_boxes.push( inputs[i] );
 }
 // get current checkbox
 for( var i in check_boxes ) if( check_boxes[i].id == selected_check_box_id ) var current_check_box = check_boxes[i];
 var current_check_box_is_checked = current_check_box.checked;  
 // get all "checked" 
 for( var i in check_boxes ) {
  if( check_boxes[i].checked ) { 
   selected_check_boxes.push( check_boxes[i] );
   count += 1;
  } 
 }
 if( current_check_box_is_checked ) {
  // checking
  if( count < 4 ) {
   current_check_box.checked = true;
   // count = 4 - disabling
   if( count == 4 ) {
    for( var i in check_boxes ) {
     if( !check_boxes[i].checked ) check_boxes[i].disabled = true;
    }
   }
  }
  else current_check_box.checked = false;
 } else {
  // unchecking
  // count is < 4 -> enabling
  for( var i in check_boxes ) {
   check_boxes[i].disabled = false;
  }
 }
}

Any help is welcome, thanks in advance.

+1  A: 

From a brief skim, your code seems much too complex for the task.

Can I suggest using something like jquery? You can quite easily select the relevant check boxes using the psudeo-selector ':checked'. Also, have a look at this check box tutorial.

If you don't want to use a library, I'd suggest first creating a function that can count the number of checked check boxes. Then create a function that can disable or enable all unchecked check boxes. Finally, combine the two, and register a function to trigger on the click event for the check boxes.

cofiem
I've checked out jQuery during the pains with this stupid thing, but I thought - why jump directly to the library, when I'm just beggining JavaScript... Also, I couldn't find a more comprehensive tutorial(even though there's a lot of info out there)
Tupak Goliam
Jumping into a library isn't such a bad idea, I'd also recommend jquery. It will not only make your life easier now, but you will find out all kinds of advanced things you can do very easily.
Jason
A: 

As cofiem said, your code looks rather complex for what you want to achieve; I recommend breaking it down into a few, smaller functions, to re-use code and make less complex.

First, implement a function to get all of the checkboxes on the page:

function getCheckboxes()
{
    var inputs = document.getElementsByTagName("input");
    var checkboxes = new Array();

    for(var i=0;i<inputs.length;++i) {
         if(inputs[i].type=="checkbox")
             checkboxes.push(inputs[i]);
    }

    return checkboxes;
}

Then a function to enable/disable the checkboxes:

function setDisabled(state) {
    var checkboxes = getCheckboxes();

    for(i=0;i<checkboxes.length;++i) {
        //Only unchecked checkboxes will need to be enabled/disabled
        if(!checkboxes[i].checked)
            checkboxes[i].disabled = state;
    }
}

Now implement your function to verify whether the checkboxes need to be enabled or disabled:

function verify_selected(checkbox) {
    var checkboxes = getCheckboxes();
     var count=0;

     for(i=0;i<checkboxes.length;++i) {
         if(checkboxes[i].checked)
             count++;
     }

     if(count>=4)
         setDisabled(true);
     else
         setDisabled(false);
}

I have changed your function declaration to pass the actual checkbox object rather than an identifier string; this is much easier to call the function:

<input type="checkbox" onClick="verify_selected(this);">
//Insert 7 of these..

As you can see the code is much easier to read and maintain, and it is much less complex.

Perspx
+1  A: 

There were a couple of things wrong. Lets give the good version first.

I also put up a demo at: http://jsbin.com/ajimi

function verify_selected(currentCheckbox) {
        var count = 0;
        var selected_check_boxes = []; // this will be fine...
        var check_boxes []; 
        var inputs = document.getElementsByTagName("input");
        for( var i in inputs ) {
            if( inputs[i].type == "checkbox" ) check_boxes.push( inputs[i] );
        }
        // get all "checked" 
        for( var i in check_boxes ) {
                if( check_boxes[i].checked ) { 
                        count += 1;
                } 
        }

        if( currentCheckbox.checked && (count == 4)) {
             for( var i in check_boxes ) 
                   if( !check_boxes[i].checked ) 
                        check_boxes[i].disabled = true;
        } else {
            for( var i in check_boxes ) 
                 check_boxes[i].disabled = false;

        }
}

In the original version, you've got a piece of code which looked like:

if (count < 4) {
   if (count == 4) {

Not gonna happen. So, that was corrected.

As you saw also in another answer, we changed the function to take out looking for an ID. Rather than figuring out the ID in some separate function (I assume you're tracking the "last clicked" by some other function which occurs), just use the this modifier to pass it into the function.

Alright, last but not least, what this would look like in jQuery. Hopefully this will help a little as to understanding how it works and why it's worth using:

(see example: http://jsbin.com/ihone)

function limitSelected(e) {    

    // get all of your checkboxes
    var checkBoxes = $(e.currentTarget).parent().children().filter('input:checkbox');

    // get the number of checkboxes checked, if 4, we'll disable
    var disableCheckBoxes = (checkBoxes.filter(':checked').length == 4);

    // enable checkboxes if we have < 4, disable if 4     
    checkBoxes.filter(':not(:checked)').each(function() {
           this.disabled = disableCheckBoxes;
    });           
}

// when the document is ready, setup checkboxes to limit selection count
// if you have a particular div in which these checkboxes reside, you should
// change the selector ("input:checkbox"), to ("#yourDiv input:checkbox")
$(function() {
  $('input:checkbox').click(limitSelected);
});

The other thing I will note about this version is that it works on the group of checkboxes within a div, as opposed to your version which will pick up checkboxes on the entire page. (which is limiting.

altCognito
Whew. Ok, that's overkill. But there you have it.
altCognito
Thank you very much for your help.
Tupak Goliam
A: 
<table class="cbMulti"> <tr><td><input type="checkbox" name="cb_specialities[]" mosReq="1" value="_UE_SPECIAL1" id="cbf5819"  mosReq="1" mosLabel="Specialities" size="0" class="required" /> <label for="cbf5819">Acne</label></td><td><input type="checkbox" name="cb_specialities[]"  value="_UE_SPECIAL11" id="cbf5829"  mosReq="1" mosLabel="Specialities" size="0" class="required" /> <label for="cbf5829">ENT</label></td><td><input type="checkbox" name="cb_specialities[]"  value="_UE_SPECIAL21" id="cbf5839"  mosReq="1" mosLabel="Specialities" size="0" class="required" /> <label for="cbf5839">Infection</label></td><td><input type="checkbox" name="cb_specialities[]"  value="_UE_SPECIAL31" id="cbf5849"  mosReq="1" mosLabel="Specialities" size="0" class="required" /> <label for="cbf5849">Psoriasis</label></td></tr> <tr><td><input type="checkbox" name="cb_specialities[]"  value="_UE_SPECIAL2" id="cbf5820"  mosReq="1" mosLabel="Specialities" size="0" class="required" /> <label for="cbf5820">AIDS</label></td><td><input type="checkbox" name="cb_specialities[]"  value="_UE_SPECIAL12" id="cbf5830"  mosReq="1" mosLabel="Specialities" size="0" class="required" /> <label for="cbf5830">Epilepsy</label></td><td><input type="checkbox" name="cb_specialities[]"  value="_UE_SPECIAL22" id="cbf5840"  mosReq="1" mosLabel="Specialities" size="0" class="required" /> <label for="cbf5840">Infertility</label></td><td><input type="checkbox" name="cb_specialities[]"  value="_UE_SPECIAL32" id="cbf5850"  mosReq="1" mosLabel="Specialities" size="0" class="required" /> <label for="cbf5850">Psychiatry</label></td></tr> <tr><td><input type="checkbox" name="cb_specialities[]"  value="_UE_SPECIAL3" id="cbf5821"  mosReq="1" mosLabel="Specialities" size="0" class="required" /> <label for="cbf5821">Asthma</label></td><td><input type="checkbox" name="cb_specialities[]"  value="_UE_SPECIAL13" id="cbf5831"  mosReq="1" mosLabel="Specialities" size="0" class="required" /> <label for="cbf5831">Eye</label></td><td><input type="checkbox" name="cb_specialities[]"  value="_UE_SPECIAL23" id="cbf5841"  mosReq="1" mosLabel="Specialities" size="0" class="required" /> <label for="cbf5841">Jaundice</label></td><td><input type="checkbox" name="cb_specialities[]"  value="_UE_SPECIAL33" id="cbf5851"  mosReq="1" mosLabel="Specialities" size="0" class="required" /> <label for="cbf5851">Renal-Stone</label></td></tr> <tr><td><input type="checkbox" name="cb_specialities[]"  value="_UE_SPECIAL4" id="cbf5822"  mosReq="1" mosLabel="Specialities" size="0" class="required" /> <label for="cbf5822">Ayurveda</label></td><td><input type="checkbox" name="cb_specialities[]"  value="_UE_SPECIAL14" id="cbf5832"  mosReq="1" mosLabel="Specialities" size="0" class="required" /> <label for="cbf5832">Fistula</label></td><td><input type="checkbox" name="cb_specialities[]"  value="_UE_SPECIAL24" id="cbf5842"  mosReq="1" mosLabel="Specialities" size="0" class="required" /> <label for="cbf5842">Kshar-Sutra</label></td><td><input type="checkbox" name="cb_specialities[]"  value="_UE_SPECIAL34" id="cbf5852"  mosReq="1" mosLabel="Specialities" size="0" class="required" /> <label for="cbf5852">Respiratory</label></td></tr> <tr><td><input type="checkbox" name="cb_specialities[]"  value="_UE_SPECIAL5" id="cbf5823"  mosReq="1" mosLabel="Specialities" size="0" class="required" /> <label for="cbf5823">Massage</label></td><td><input type="checkbox" name="cb_specialities[]"  value="_UE_SPECIAL15" id="cbf5833"  mosReq="1" mosLabel="Specialities" size="0" class="required" /> <label for="cbf5833">Gall-Stone</label></td><td><input type="checkbox" name="cb_specialities[]"  value="_UE_SPECIAL25" id="cbf5843"  mosReq="1" mosLabel="Specialities" size="0" class="required" /> <label for="cbf5843">Leucoderma</label></td><td><input type="checkbox" name="cb_specialities[]"  value="_UE_SPECIAL35" id="cbf5853"  mosReq="1" mosLabel="Specialities" size="0" class="required" /> <label for="cbf5853">Sex</label></td></tr> <tr><td><input type="checkbox" name="cb_specialities[]"  value="_UE_SPECIAL6" id="cbf5824"  mosReq="1" mosLabel="Specialities" size="0" class="required" /> <label for="cbf5824">Beauty</label></td><td><input type="checkbox" name="cb_specialities[]"  value="_UE_SPECIAL16" id="cbf5834"  mosReq="1" mosLabel="Specialities" size="0" class="required" /> <label for="cbf5834">GIT</label></td><td><input type="checkbox" name="cb_specialities[]"  value="_UE_SPECIAL26" id="cbf5844"  mosReq="1" mosLabel="Specialities" size="0" class="required" /> <label for="cbf5844">Migraine</label></td><td><input type="checkbox" name="cb_specialities[]"  value="_UE_SPECIAL36" id="cbf5854"  mosReq="1" mosLabel="Specialities" size="0" class="required" /> <label for="cbf5854">Skin</label></td></tr> <tr><td><input type="checkbox" name="cb_specialities[]"  value="_UE_SPECIAL7" id="cbf5825"  mosReq="1" mosLabel="Specialities" size="0" class="required" /> <label for="cbf5825">Cancer</label></td><td><input type="checkbox" name="cb_specialities[]"  value="_UE_SPECIAL17" id="cbf5835"  mosReq="1" mosLabel="Specialities" size="0" class="required" /> <label for="cbf5835">Gynae</label></td><td><input type="checkbox" name="cb_specialities[]"  value="_UE_SPECIAL27" id="cbf5845"  mosReq="1" mosLabel="Specialities" size="0" class="required" /> <label for="cbf5845">Pain</label></td><td><input type="checkbox" name="cb_specialities[]"  value="_UE_SPECIAL37" id="cbf5855"  mosReq="1" mosLabel="Specialities" size="0" class="required" /> <label for="cbf5855">Urinary</label></td></tr> <tr><td><input type="checkbox" name="cb_specialities[]"  value="_UE_SPECIAL8" id="cbf5826"  mosReq="1" mosLabel="Specialities" size="0" class="required" /> <label for="cbf5826">Dental</label></td><td><input type="checkbox" name="cb_specialities[]"  value="_UE_SPECIAL18" id="cbf5836"  mosReq="1" mosLabel="Specialities" size="0" class="required" /> <label for="cbf5836">Hair</label></td><td><input type="checkbox" name="cb_specialities[]"  value="_UE_SPECIAL28" id="cbf5846"  mosReq="1" mosLabel="Specialities" size="0" class="required" /> <label for="cbf5846">Panchkarma</label></td><td><input type="checkbox" name="cb_specialities[]"  value="_UE_SPECIAL38" id="cbf5856"  mosReq="1" mosLabel="Specialities" size="0" class="required" /> <label for="cbf5856">Wt. Gain</label></td></tr> <tr><td><input type="checkbox" name="cb_specialities[]"  value="_UE_SPECIAL9" id="cbf5827"  mosReq="1" mosLabel="Specialities" size="0" class="required" /> <label for="cbf5827">Depression</label></td><td><input type="checkbox" name="cb_specialities[]"  value="_UE_SPECIAL19" id="cbf5837"  mosReq="1" mosLabel="Specialities" size="0" class="required" /> <label for="cbf5837">Heart</label></td><td><input type="checkbox" name="cb_specialities[]"  value="_UE_SPECIAL29" id="cbf5847"  mosReq="1" mosLabel="Specialities" size="0" class="required" /> <label for="cbf5847">Paralysis</label></td><td><input type="checkbox" name="cb_specialities[]"  value="_UE_SPECIAL39" id="cbf5857"  mosReq="1" mosLabel="Specialities" size="0" class="required" /> <label for="cbf5857">Wt. Loss</label></td></tr> <tr><td><input type="checkbox" name="cb_specialities[]"  value="_UE_SPECIAL10" id="cbf5828"  mosReq="1" mosLabel="Specialities" size="0" class="required" /> <label for="cbf5828">Diabetes</label></td><td><input type="checkbox" name="cb_specialities[]"  value="_UE_SPECIAL20" id="cbf5838"  mosReq="1" mosLabel="Specialities" size="0" class="required" /> <label for="cbf5838">Hepatitis</label></td><td><input type="checkbox" name="cb_specialities[]"  value="_UE_SPECIAL30" id="cbf5848"  mosReq="1" mosLabel="Specialities" size="0" class="required" /> <label for="cbf5848">Piles</label></td><td><input type="checkbox" name="cb_specialities[]"  value="_UE_SPECIAL40" id="cbf5858"  mosReq="1" mosLabel="Specialities" size="0" class="required" /> <label for="cbf5858">Yoga</label></td></tr> </table>

please help to apply this script to this table i want to select 6 boxs without changing the code .(the whole code i hv pasted here)

thanx