tags:

views:

391

answers:

5

Hi everyone, I have the following code. I need to see how many checkboxes have been checked in my form and if there are more than four display error and uncheck the last check box,everything is working but how can I uncheck the last check box, thanks

   function SetHiddenFieldValue()

   {
      var checks = document.getElementById('toppings').getElementsByTagName('input');
      var toppings = new Array();
      var randomNumber = Math.floor((Math.random() * 9000) + 100);
      var totalChecked = 0;
      var itemPrice = 5.99;

    for (i = 0; i < checks.length; i++)
    {
        if (checks[i].checked)
        {
            toppings[i] = checks[i].value;
            totalChecked += 1; 
        }
    }

    if (totalChecked > 4) {
        alert("You can only choose up to Max of 4 Toppings");   
    } else {    
        itemPrice = itemPrice + (totalChecked * 0.99);  
        document.getElementById('my-item-name').value = toppings.join("\t");
        document.getElementById('my-item-id').value = randomNumber;
        document.getElementById('my-item-price').value = itemPrice;
    }
}

And my form is:

<form id="pizza" name="pizza" method="post" action="" class="jcart">
    <input type="hidden" name="my-item-id" id="my-item-id" value="" />
    <input type="hidden" name="my-item-name" id="my-item-name" value="" />
    <input type="hidden" name="my-item-price" id="my-item-price" value="" />
    <input type="hidden" name="my-item-qty" value="1" />
    <input type="submit" name="my-add-button" value=" add " />
</form>
+1  A: 

Keep track of the last checked checkbox and set its checked property to false:

// ...
var lastChecked; // Will be used in loop below
for (i = 0; i < checks.length; i++)
{
    if (checks[i].checked)
    {
        toppings[i] = checks[i].value;
        totalChecked += 1;
        lastChecked = i; // Store the checkbox as last checked
    }
}

if (totalChecked > 4) {
    alert("You can only choose up to Max of 4 Toppings");
    checks[lastChecked].checked = false; // Uncheck the last checked checkbox
} else {
// ...

If you want to uncheck all but the four first ones, do it like this:

// ...
for (i = 0; i < checks.length; i++)
{
    if (checks[i].checked)
    {
        toppings[i] = checks[i].value;
        totalChecked += 1;
        if (totalChecked > 4) checks[i].checked = false; // Uncheck checkbox
    }
}
Blixt
If the user is nice enough to click particular checkboxes in order, then this will work, but if the user clicks items 2, 4, 6, and 8, and then checks option 1, then what will happen is that item 8 gets deselected, instead of item 1, which is what should happen.
Yuliy
Well, that depends entirely on what he means by "last"
Blixt
A: 

Well you'll need to somehow pass into this method which particular checkbox was just checked, and then if the total checked count test fails, then just set that checkbox's .checked property to false.

Yuliy
A: 

What if the user checked more than five?

One way to do it is create a javascript function that returns false if more than four checkboxes are checked. In each checkbox, hook the new function like this:

<input type="checkbox" onclick="return myNewFunction(this);">

This will inhibit the user from checking any checkbox that is the fifth one.

Robert Harvey
+2  A: 

I think that I would handle this differently. I'd have a click handler on each checkbox that counts the number of checked boxes (including the current if it is being checked) to see if it is greater than 4. If it is, then I would stop the current event, pop the alert, and reset the state of the checkbox causing the alert. This way it would always popup when clicking the fourth checkbox.

To handle the case where javascript is disabled, you'd need to make sure that your server-side code validates that no more than 4 checkboxes have been checked.

JQuery example:

$(':checkbox').click( function() {
   if ($(this).val() == 'on') { // need to count, since we are checking this box
      if ($(':checkbox:checked').length > 4) {
         alert( "You can only choose up to a maximum of 4 toppings." );
         $(this).val('off');
      }
   }
});

Note if you had other types of checkboxes on the page you could use a class to distinguish them. In that case, the selector becomes (':checkbox.topping') and (':checkbox.topping:checked').

tvanfosson
Use `input:checkbox` etc. because `:checked` is the same as `*:checkbox` which means it will test all elements.
Blixt
I meant "...because `:checkbox` is the same...", of course.
Blixt
A: 

Alternatively, you could prevent the user from making an invalid action in the first place, by disabling all the other boxes once four of them are checked, and displaying a message like "Choose up to four of these." This way, you don't let the user do something you know is invalid and then scold them.

aem