Reputation: 1183
I'm trying to disable checkboxes for a selected item if conditions are met. An alert is issued if a user selects more than one Tues morning class or more than one Tues afternoon class. The alert is working correctly but it does not disable the checkbox and allows the user to continue selecting as many boxes as they like.
I was able to disable the checkbox using something like
$(this).prop("disabled", true);
but it was disabling any checkbox that was selected and not the one for the specific class I'm checking for. I now have changed to look for the class, but it is not disabling, and a bit stumped on where to go from here.
//Activities
var $activities = $('.activities input[type="checkbox"]');
var tuesMorn = 0;
var tuesAft = 0;
var wedMorn = 0
var wedAft = 0;
var main = 0;
var total = 0;
//On change of activity select boxes, looks for duplicate times and creates total $ amount
$activities.change(function() {
var activityClass = $(this).closest('input').attr("class");
var isChecked = this.checked;
$activities.not(this).prop('disabled', false);
if (activityClass === 'tues_morn') {
tuesMorn = isChecked ? tuesMorn + 1 : tuesMorn - 1;
total = isChecked ? total + 100: total -100;
} else if (activityClass === 'tues_aft') {
tuesAft = isChecked ? tuesAft + 1 : tuesAft - 1;
total = isChecked ? total + 100: total -100;
} else if (activityClass === 'wed_morn'){
wedMorn = isChecked ? wedMorn + 1 : wedMorn - 1;
total = isChecked ? total + 100: total -100;
} else if (activityClass === 'wed_aft'){
wedAft = isChecked ? wedAft + 1 : wedAft - 1;
total = isChecked ? total + 100: total -100;
} else if (activityClass === 'main'){
main = isChecked ? main + 1 : main - 1;
total = isChecked ? total + 200: total -200;
}
if (tuesMorn > 1) {
alert("You Signed Up For Too Many Morning Classes");
$(".tues_morn", this).prop('disabled', true);
}
if (tuesAft > 1) {
alert("You Signed Up For Too Many Afternoon Classes");
$(".tues_aft", this).prop('disabled', true);
}
document.getElementById('Totalcost').innerHTML = "$" + total;
});
.error, .error_name, .error_email, .error_activities, .error_cc,
.error_cvv, .error_zip {
display: none;
color: red;
margin-bottom: 5px;
position: relative;
}
.error_show{
color: red;
margin-left: 10px;
}
<body>
<div class="container">
<header>
<span>Register for</span>
<h1>Full Stack Conf</h1>
</header>
<form id='contact' action="index.html" method="post">
<fieldset>
<legend>Basic Info</legend>
<label for="name">Name:</label>
<input type="text" id="name" name="user_name">
<span class="error_name">A name is required</span>
<label for="mail">Email:</label>
<input type="email" id="mail" name="user_email">
<span class="error_email">A valid email address is required</span>
<label for="title">Job Role</label>
<select id="title" name="user_title">
<option value="full-stack js developer">Full Stack JavaScript Developer</option>
<option value="front-end developer">Front End Developer</option>
<option value="back-end developer">Back End Developer</option>
<option value="designer">Designer</option>
<option value="student">Student</option>
<option value="other">Other</option>
</select>
</fieldset>
<div><input placeholder='Your Job Role' id='other-title'></input></div>
<fieldset class="shirt">
<legend>T-Shirt Info</legend>
<div>
<label for="size">Size:</label>
<select id="size" name="user_size">
<option value="small">S</option>
<option value="medium" selected>M</option>
<option value="large">L</option>
<option value="extra large">XL</option>
</select>
</div>
<div>
<label for="design">Design:</label>
<select id="design" name="user_design">
<option>Select Theme</option>
<option value="js puns">Theme - JS Puns</option>
<option value="heart js">Theme - I ♥ JS</option>
</select>
</div>
<div id="colors-js-puns" class="">
<label for="color">Color:</label>
<select id="color">
<option>Select Color</option>
<option value="cornflowerblue" class="js_puns">Cornflower Blue (JS Puns shirt only)</option>
<option value="darkslategrey" class="js_puns">Dark Slate Grey (JS Puns shirt only)</option>
<option value="gold" class="js_puns">Gold (JS Puns shirt only)</option>
<option value="tomato" class="js">Tomato (I ♥ JS shirt only)</option>
<option value="steelblue" class="js">Steel Blue (I ♥ JS shirt only)</option>
<option value="dimgrey" class="js">Dim Grey (I ♥ JS shirt only)</option>
</select>
</div>
</fieldset>
<fieldset class="activities">
<legend>Register for Activities</legend>
<label><input type="checkbox" name="all" class="main">Main Conference — $200</label>
<label><input type="checkbox" name="js-frameworks" class="tues_morn"> JavaScript Frameworks Workshop — Tuesday 9am-12pm, $100</label>
<label><input type="checkbox" name="js-libs" class="tues_aft"> JavaScript Libraries Workshop — Tuesday 1pm-4pm, $100</label>
<label><input type="checkbox" name="express" class="tues_morn"> Express Workshop — Tuesday 9am-12pm, $100</label>
<label><input type="checkbox" name="node" class="tues_aft"> Node.js Workshop — Tuesday 1pm-4pm, $100</label>
<label><input type="checkbox" name="build-tools" class="wed_morn"> Build tools Workshop — Wednesday 9am-12pm, $100</label>
<label><input type="checkbox" name="npm" class="wed_aft"> npm Workshop — Wednesday 1pm-4pm, $100</label>
</fieldset>
<span class="error_activities">One Activity Must Be Selected!</span>
Total Amount : <span id="Totalcost"> </span>
<fieldset>
<legend>Payment Info</legend>
<label for="payment">I'm going to pay with:</label>
<select id="payment" name="user_payment">
<option value="select_method">Select Payment Method</option>
<option value="credit card">Credit Card</option>
<option value="paypal">PayPal</option>
<option value="bitcoin">Bitcoin</option>
</select>
<div id="credit-card" class="credit-card">
<div class="col-6 col">
<label for="cc-num">Card Number:</label>
<input id="cc-num" name="user_cc-num" type="text">
</div>
<div class="col-3 col">
<label for="zip">Zip Code:</label>
<input id="zip" name="user_zip" type="text">
</div>
<div class="col-3 col">
<label for="cvv">CVV:</label>
<input id="cvv" name="user_cvv" type="text">
</div>
<span class="error_cc">Sorry card number has wrong # of digits or incorrect entry.</span>
<span class="error_zip">Sorry that's not a valid zip code.</span>
<span class="error_cvv">Sorry you've entered an invalid CVV.</span>
<label for="exp-month">Expiration Date:</label>
<select id="exp-month" name="user_exp-month">
<option value="1">1 - January</option>
<option value="2">2 - February</option>
<option value="3">3 - March</option>
<option value="4">4 - April</option>
<option value="5">5 - May</option>
<option value="6">6 - June</option>
<option value="7">7 - July</option>
<option value="8">8 - August</option>
<option value="9">9 - September</option>
<option value="10">10 - October</option>
<option value="11">11 - November</option>
<option value="12">12 - December</option>
</select>
<label for="exp-year">Expiration Year:</label>
<select id="exp-year" name="user_exp-year">
<option value="2016">2016</option>
<option value="2017">2017</option>
<option value="2018">2018</option>
<option value="2019">2019</option>
<option value="2020">2020</option>
</select>
</div>
<div id="paypal">
<p>If you selected the PayPal option we'll take you to Paypal's site to set up your billing information, when you click “Register” below.</p>
</div>
<div id="bitcoin">
<p>If you selected the Bitcoin option we'll take you to the Coinbase site to set up your billing information. Due to the nature of exchanging Bitcoin, all Bitcoin transactions will be final.</p>
</div>
</fieldset>
<!-- Submit Button -->
<div id="contact_submit">
<button type="submit">Register</button>
</div>
</form>
</div>
<script
src="https://code.jquery.com/jquery-1.12.4.js"
integrity="sha256-Qw82+bXyGq6MydymqBxNPYTaUXXq7c8v3CwiYwLLNXU="
crossorigin="anonymous"></script>
<script src="js/main.js"></script>
Upvotes: 2
Views: 936
Reputation: 28196
In the spirit of jquery "write less do more" you could do the following:
$('.activities').on('click','input[type=checkbox]',function(){
$(this).siblings('.'+this.className).prop('disabled',this.checked);
// calculate total amount after each change:
$('#total').val($.makeArray($('input:checked').map(function(o){
return parseFloat(this.nextSibling.textContent.replace(/^.*\$/,'').trim());
})).reduce(function(sum,val){return sum+val},0));
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<fieldset class="activities">
<legend>Register for Activities</legend>
<input type="checkbox" name="all" class="main" />Main Conference — $200
<input type="checkbox" name="js-frameworks" class="tues_morn" /> JavaScript Frameworks Workshop — Tuesday 9am-12pm, $100
<input type="checkbox" name="js-libs" class="tues_aft" /> JavaScript Libraries Workshop — Tuesday 1pm-4pm, $100
<input type="checkbox" name="express" class="tues_morn" /> Express Workshop — Tuesday 9am-12pm, $100
<input type="checkbox" name="node" class="tues_aft" /> Node.js Workshop — Tuesday 1pm-4pm, $100
<input type="checkbox" name="build-tools" class="wed_morn" /> Build tools Workshop — Wednesday 9am-12pm, $100
<input type="checkbox" name="npm" class="wed_aft" /> npm Workshop — Wednesday 1pm-4pm, $100
</fieldset>
total amount: <input type="text" id="total" />
I removed the <label>
tags since they did not seem to serve any purpose. This made it much easier to use the siblings()
function to identify all the other siblings with identical classNames. So the whole action essentially takes place in the one line
$(this).siblings('.'+this.className).prop('disabled',this.checked)
I removed the alert since - in my opinion - it disturbs the flow of the action. But feel free to work it back in again ...
Edit:
I added the summation functionality. I used the textual information given after each checkbox to get the price for each course.
Upvotes: 3
Reputation: 1834
I changed your code a little, because the logic wasn't working for me.
Initially, you shouldn't re-enable all activities on every single change, so this line goes away:
$activities.not(this).prop('disabled', false);
Then, you should check if activities are from the same group to either enable or disable them, so I changed your if to:
if ($this.is('.tues_morn'))
Finally, enabled or disabled status depends on whether there is a single selection, so I wrote this:
$(".tues_morn").not(this).prop('disabled', tuesMorn > 0);
You can check it out here: https://jsfiddle.net/dobu5qpt/5/
Upvotes: 2
Reputation: 514
After just editing a line it worked.
Why did you write $(".tues_aft", this).prop('disabled', true);
?
$(this).prop('disabled', true);
is enough since we are in the event callback.
https://jsfiddle.net/dobu5qpt/2/
EDIT: This only disables the last one clicked, if you want to make all the .tues_aft disabled, use $(".tues_aft").prop('disabled', true);
instead.
Upvotes: -2
Reputation: 635
You don't need this
as the second argument to $
:
if (tuesMorn > 1) {
alert("You Signed Up For Too Many Morning Classes");
$(".tues_morn").prop('disabled', true);
}
if (tuesAft > 1) {
alert("You Signed Up For Too Many Afternoon Classes");
$(".tues_aft").prop('disabled', true);
}
Upvotes: 1