views:

627

answers:

6

Hi I created a javascript function to check if the number of modules selected is greater than a given value. So each time a checkbox is called the function is called, and the function goes through all the checkboxes and calculates the total to see if it's greater. But the problem is when the user checks the checkbox and if the total credits is greater than the value, I want to set the checkbox as checked=false. But I don't which checkbox to undo. Is there any undo last click function in javascript?

+1  A: 

I know this isn't the answer you were looking for, but wouldn't it be a better user experience to disable all unchecked checkboxes when the maximum number of checks has been reached?

Richard Slater
This is not a normal behavior for any user... it would not serve as an user-friendly experience.
Seb
@SebaGR: why? displaying a message that informs the user that the total amount has been reached and then disabling all unchecked boxes and visually mark the appropriate labels sounds perfectly usable to me
Christoph
I agree. You could extend the experience by calculating the amount remaining and disabling those checkboxes which if checked would add to more than the max amount. That way, if max=50 and you've selected 47, checkbox with value=5 would be disabled and checkbox with value=3 will still be available :)
Danita
A: 

I dont think there is, but you can always save a reference to the last checked box, so when you have to un-check it, you have it right there.

Mg
That is exactly what he's asking for! :P
Seb
Same answer you gave him, without the code you put there xD.
Mg
+5  A: 

Not really, but you could fake it easily enough by saving the last box clicked. This code may not work verbatim, but you get the idea:

<script>
var last_checked_box;

function onBoxClicked( box ) {
   if ( box.checked ) last_checked_box = box;
}

function undoLastBox() {
   if ( last_checked_box ) last_checked_box.checked = false;
}
</script>

<input type="checkbox" id="box1" onClick="onBoxClicked(this)"/>
...
Eric Petroelje
This would do the trick, but here you're missing the proper functions to calculate the upper limit. I'm giving you a complete solution in my answer :)
Seb
@Eric: why save the boxes' id and not a reference to the box itself, ie `last_checked_box = box`?
Christoph
@SebaGR - Your answer is better for his particular situation, but somebody else who might find this question on a Google search might not have the same requirements. I also didn't want to assume he would be using jQuery.
Eric Petroelje
@Christoph - no particular reason, it was just the first thing I thought of :)
Eric Petroelje
@Eric: ok. it's just that doing it this way reminds me of telling the person standing next to you to call on your mobile if they want to speak to you ;)
Christoph
@Christoph - ok, ok, edited to remove unnecessary cruft :)
Eric Petroelje
+5  A: 

Using jQuery, you could do something like:

var MAX_CREDITS = 50; // just as an example
$("input[type=checkbox]").change(function (){
  var totalCredits = 0;
  $("input[type=checkbox]").each(function (){
    // augment totalCredits accordingly to each checkbox.
  });

  if(totalCredits > MAX_CREDITS){
    $(this).removeAttr("checked");
  }
});

If you've never used jQuery before, this surely is like a pain for your eyes; but as you can see, it's very powerful and your problem can be solved in few lines. I'd recommend you learning it and giving it a try ;)

Seb
A: 

I suggest either testing if the max number of objects has been checked and if true remove the check all in the same method or you set the value to some hidden text box to the id of your last checked check box so that you can reference it again.

Eppz
A: 

Here's a minimal, but fully functional and jQuery-less solution:

<script>
function isBox(element) {
    return element.form && element.form === document.forms[0] &&
        element.nodeName.toLowerCase() === 'input' &&
        element.type === 'checkbox';
}

function remaining(dR) {
    var field = document.forms[0].elements[0],
        value = +field.value;

    if(dR) return field.value = value + dR;
    else return value;
}

function listener(event) {
    var box = (event && event.target) ||
        (window.event && window.event.srcElement);

    if(isBox(box)) {
        if(box.checked) {
            if(remaining() > 0)
                remaining(-1);
            else box.checked = false;
        }
        else remaining(+1);
    }
}

if(document.addEventListener)
    document.addEventListener('click', listener, false);
else if(document.attachEvent)
    document.attachEvent('onclick', listener);
</script>
<form>
 <p>remaining: <input type="text" readonly="readonly" value="2"></p>
 <p><input type="checkbox" id="b1"><label for="b1">box1</label></p>
 <p><input type="checkbox" id="b2"><label for="b2">box2</label></p>
 <p><input type="checkbox" id="b3"><label for="b3">box3</label></p>
</form>
Christoph