Reputation: 165
I am trying to build a ticketing system which will allow up to 4 people (kids in this case) to be selected out of 3 age groups (2-12, 12-18, 18+), which are presented in 3 different select boxes:
<div class="selects">
<div class="select-one select-box">
<label>Kids Ages 2-12</label>
<select id="kids1">
<option value="0">--select--</option>
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
</select>
</div>
<div class="select-two select-box">
<label>Kids Ages 12-18</label>
<select id="kids2">
<option value="0">--select--</option>
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
</select>
</div>
<div class="select-three select-box">
<label>Kids Ages 18+</label>
<select id="kids3">
<option value="0">--select--</option>
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
</select>
<div class="error-box">
</div>
</div>
</div>
Each box has initially 4 options, but naturally I want to limit the choices as the process goes on: If in a certain select box 2 kids are chosen, then you can't choose more than 2 kids alltogether in the next 2 select boxes, etc.
I've started in trying to disable options in the 2nd and 3rd select boxes after I choose "1" in the 1st select box:
$("#kids1").change(function() {
var kidsOne = $(this).val();
if (kidsOne === "1") {
$("#kids2").children('option:gt(3)').prop('disabled', true);
$("#kids3").children('option:gt(3)').prop('disabled', true);
} else {
$("#kids2").children('option:gt(1)').prop('disabled', false);
$("#kids3").children('option:gt(1)').prop('disabled', false);
}
}).change();
But then I understood this is going to be hell when I move on to the next boxes. So I thought the best way will be to set a maximum of all values combined, and somehow set restrictions by this. But I'm not sure how.
EDIT:
I've changes the selects to input numbers and tried to limit each changed input according to other input values and max 4:
HTML:
<label>Kids Ages 2-12</label> <input class="qty" type="number" value="0" min="0" max="4" id="kids1"><br>
<label>Kids Ages 12-18</label> <input class="qty" type="number" value="0" min="0" max="4" id="kids2"><br>
<label>Kids Ages 18+</label> <input class="qty" type="number" value="0" min="0" max="4" id="kids3"><br>
jQuery:
$(document).on("change", ".qty", function() {
var sum = 0;
$(".qty").each(function() {
sum += +$(this).val();
});
var thisSum = $(this).val();
var sumOthers = parseInt(sum) - (thisSum);
var limitMax = parseInt(4) - (sumOthers);
$(this).attr("max", limitMax);
});
It basically works, the Problem is it still allows the first increment even if other inputs are still summing up to 4. Any ideas?
Upvotes: 0
Views: 591
Reputation: 4391
The code below is a good beginning. Currently it only goes from first to last select/input by resetting others.
var total = 0;
var max = 4;
$('#total span').html(total);
$('#kids1').on('change', function() {
var kids1 = parseInt($(this).val());
let allowed = max - kids1;
$('#kids2').val(0).attr('max', allowed);
$('#kids3').val(0).attr('max', allowed);
total = kids1;
$('#total span').html(total);
});
$('#kids2').on('change', function() {
var kids1 = parseInt($('#kids1').val());
var kids2 = parseInt($(this).val());
let allowed = max - (kids1 + kids2)
$('#kids3').val(0).attr('max', allowed);
total = kids1 + kids2
$('#total span').html(total);
});
label {
width: 125px;
display: inline-block;
}
input {
padding: 3px;
}
#total {
margin-top: 5px;
padding-top: 5px;
border-top: 1px solid #bbb;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<label>Kids Ages 2-12</label> <input type="number" value="0" min="0" max="4" id="kids1"><br>
<label>Kids Ages 12-18</label> <input type="number" value="0" min="0" max="4" id="kids2"><br>
<label>Kids Ages 18+</label> <input type="number" value="0" min="0" max="4" id="kids3"><br>
<div id="total">
Total: <span></span>
</div>
Upvotes: 1
Reputation: 11
There are two ways of approaching this with the second offering less javascript.
The first is to attach a change event to each of the selects and keep a running count of current picks. If the current change would make your running count top out than you can cancel it right then and there via preventDefault (or otherwise reverse it). Keep in mind that in order to do multiple selections in default html without any kind of selectpicker library you will have to include the 'multiple' attribute in your select element. In addition your user will also hold the ctrl button to make multiple selections.
The second and possibly clearer options is to use option groups so that you only require a single select instead of multiple; with each group being the age bracket. Again you'd likely need to do some javascript to manually check but at least there would be less of it.
Upvotes: 1