How to limit the user to check only certains checkbox in a list (based on his previous check)
i have a list of checkboxes that have an incremental list of value.
i need to apply those rules :
- the user can check 1 checkbox min to 3 checkboxes max
- the user can only check contiguous checkboxes
(example :
- the user checks the #6,
- then only #5 or #开发者_如何学运维7 are available,
- the user checks the #7
- then only #5 or #8 are available.
- the user checks #8,
- then no more checkboxes are available !
i have this list of checkboxes :
<form id="time-slot" action="" method="POST">
<input type="checkbox" name="tranche" value="1" />
<input type="checkbox" name="tranche" value="2" />
<input type="checkbox" name="tranche" value="3" />
<input type="checkbox" name="tranche" value="4" />
<input type="checkbox" name="tranche" value="5" />
<input type="checkbox" name="tranche" value="6" />
<input type="checkbox" name="tranche" value="7" />
<input type="checkbox" name="tranche" value="8" />
<input type="checkbox" name="tranche" value="9" />
<input type="checkbox" name="tranche" value="10" />
<input type="submit" value="Send" />
</form>
how could i handle those rules with jquery ? thx for your help !
$("#time-slot input[type='checkbox']").click(function() {
// Disable all unchecked
$('input[type=checkbox]:not(:checked)').attr('disabled','disabled');
// If 3 are checked we are done
if($('input[type=checkbox]:checked').length == 3)
return;
// If the checkbox either side of this one is checked, we only have 1 option
if($(this).prev().is(':checked') && $(this).next().is(':checked')){
$(this).removeAttr('disabled');
return;
}
// Enable the checkboxes before and after the current selection
$('input[type=checkbox]:checked').prev().removeAttr('disabled');
$('input[type=checkbox]:checked').next().removeAttr('disabled');
// If none are checked, enable all
if($('input[type=checkbox]:checked').length == 0)
$('input[type=checkbox]').removeAttr('disabled');
});
this should cover all eventualities. See it in action here... http://jsfiddle.net/JcCdD/
UPDATE
The difference here is that we have to use prevAll and nextAll to skip over br and label elements. As these work slightly differently when using a collection of elements, we have to break it into an each statement.
$("#time-slot input[type='checkbox']").click(function() {
// Disable all unchecked
$('input[type=checkbox]:not(:checked)').attr('disabled','disabled');
// If 3 are checked we are done
if($('input[type=checkbox]:checked').length == 3)
return;
// If the checkbox either side of this one is checked, we only have 1 option
if($(this).prevAll('input').first().is(':checked') && $(this).nextAll('input').first().is(':checked')){
$(this).removeAttr('disabled');
return;
}
// Enable the checkboxes before and after the current selection
$('input[type=checkbox]:checked').each(function(){
$(this).prevAll('input').first().removeAttr('disabled');
$(this).nextAll('input').first().removeAttr('disabled');
});
// If none are checked, enable all
if($('input[type=checkbox]:checked').length == 0)
$('input[type=checkbox]').removeAttr('disabled');
});
new example here... http://jsfiddle.net/bEjTf/
Hook into the onchange
event of the limiting checkbox, setting the disabled
attribute of the checkboxes that are now unavailable if the user just checked the box, unsetting the attribute otherwise. Illustrative example:
$(document).ready(function(){
$('#ch1').change(function(){
if($(this).is(':checked')) {
$("#ch2").attr('disabled','disabled');
} else {
$("#ch2").removeAttr('disabled');
}
});
});
Also, see this jsFiddle demo. Obviously, this needs adapting for your specific situation, particularly when it comes to checking what boxes to enable/disable in every situation, but I get the feeling that that's not your problem.
Here's a workaround:
$("#time-slot").submit(function(){
var $checks = $(this).find(":checkbox");
if($checks.size() > 3) { alert("Max 3 checked checks allowed"); return false;}
if($checks.size() == 0) { alert("Check at least one!"); return false;}
var prevCheckedIndex == null;
var contiguous = true;;
$checks.each(function(i, elem){
if(!$(this).is(":checked")) return;
if(prevCheckedIndex != null && prevCheckedIndex != i-1)
return (contiguous = false);
prevCheckedIndex = i;
});
if(!contiguous) { alert("Checked boxes must be coniguous!") return false;}
});
This will trigger on form submit, but validates all the conditions you want.
Hope this helps. Cheers
Like this: http://jsfiddle.net/j9MJF/1/
$("#time-slot input[type='checkbox']").click(function() {
var me = $(this);
var clickedIndex= me.prevAll().length;
var totalChecked = $("#time-slot input[type='checkbox']:checked").length;
$("#time-slot input[type='checkbox']").each(function() {
var myIndex = $(this).prevAll().length;
if(!$(this).is(":checked")) $(this).attr("disabled", "disabled");
if(totalChecked < 3) {
if(myIndex == clickedIndex
|| $("#time-slot input[type='checkbox']").eq(myIndex+1).is(":checked")
|| $("#time-slot input[type='checkbox']").eq(myIndex-1).is(":checked") ) {
$(this).removeAttr("disabled");
}
}
});
});
精彩评论