I am attempting to set a variable limit on how many checkboxes can be set, based on a previous selection.
In my code I have an option input, where you select your choice (which is the templates and limitTemplate variables). Then I have some checkbox inputs. Let's say I chose my the option for 2 cards. Then I want to choose two checkboxes below it and then not be able to choose any additional cards.
For some reason my code is saying I am reaching the limit on my first selection, regardless of the card limit option. As you can see in my #template-number (where is says "Choose x templates from below") that I am getting the limitTemplate to work, at least at that point.
Does anyone see what I am doing wrong?
The part of the code where I am trying to restrict the limit is here:
if ($(templateCount >= limitTemplate)) {
event.preventDefault();
$('.tp-template-check[type="checkbox"]').not(':checked').prop('disabled', true);
alert("You reached your limit");
}
ps - it looks like a lot of HTML, but it is basically checkbox inputs.
Here is a fiddle in case you prefer this method.
jQuery.fn.fadeBoolToggle = function(bool) {
return bool ? this.fadeIn(400) : this.fadeOut(400);
}
$('#tp-frequency').on('change', function() {
var templates = $('#tp-frequency option:selected').val();
$('#template-number').html(templates);
// Setting limit for TP templates
$('.tp-template-check').on('change', function() {
var limitTemplate = templates;
if (!this.checked || $('.tp-template-check:checked').length <= limitTemplate) {
$(this).parents('.product-wrap:first').find('.checkmark-img').fadeBoolToggle(this.checked);
var templateCount = $('.tp-template-check:checked').length;
if ($(templateCount > 0)) {
$('#templateCount').html(templateCount + " Template" + (templateCount == 1 ? "" : "s") + " Selected");
}
if ($(templateCount >= limitTemplate)) {
event.preventDefault();
$('.tp-template-check[type="checkbox"]').not(':checked').prop('disabled', true);
alert("You reached your limit");
}
if (templateCount == limitTemplate) {
$('#templateCountComplete').fadeBoolToggle($('.tp-template-check:checked').length == limitTemplate).addClass('block');
} else if (templateCount > limitTemplate) {
$('.tp-template:checkbox').attr('checked', false);
$('#templateCountComplete').hide();
}
} else {
$('#templateCountComplete').hide();
}
}); //End of .tp-template-check func
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<h2 class="section-subtitle">Choose the limit</h2>
<p class="small-description margin25">* Some choices result in more/less cards.</p>
<select id="tp-frequency" class="option-input">
<option value='' disabled selected>Please choose option</option>
<option value='5'>5 cards</option>
<option value='3'>3 cards</option>
<option value='2'>2 cards</option>
</select>
<div id="tp-template-section">
<!-- Template Section -->
<h2 class="section-subtitle">Choose <span id="template-number"></span> templates from below.</h2>
<p id="test2"></p>
<p id="templateCount"></p>
<div id="templateCountComplete"><img src="images/checkmark.png" alt="Template Selection Complete" id="templateCountImg"></div>
<div id="tp-template-wrap">
<div class="tp-template">
<div class="product-wrap">
<label for="tp-winter" class="package-check-toggle">
<h4 class="tp-template-title">Winter</h4>
<img src="images/tp-winter.png" class="tp-template-img">
<img src="images/checkmark-circle.png" class="checkmark-img total-center">
</label>
<input type="checkbox" class="tp-template-check" data-template="Winter" data-template-image="<img src='images/tp-winter.png' class='review-img'>" id="tp-winter" value="Winter">
</div>
</div>
<div class="tp-template">
<div class="product-wrap">
<label for="tp-spring" class="package-check-toggle">
<h4 class="tp-template-title">Spring</h4>
<img src="images/tp-spring.png" class="tp-template-img">
<img src="images/checkmark-circle.png" class="checkmark-img total-center">
</label>
<input type="checkbox" class="tp-template-check" data-template="Spring" data-template-image="<img src='images/tp-spring.png' class='review-img'>" id="tp-spring" value="Spring">
</div>
</div>
<div class="tp-template">
<div class="product-wrap">
<label for="tp-summer" class="package-check-toggle">
<h4 class="tp-template-title">Summer</h4>
<img src="images/tp-summer.png" class="tp-template-img">
<img src="images/checkmark-circle.png" class="checkmark-img total-center">
</label>
<input type="checkbox" class="tp-template-check" data-template="Summer" data-template-image="<img src='images/tp-summer.png' class='review-img'>" id="tp-summer" value="Summer">
</div>
</div>
<div class="tp-template">
<div class="product-wrap">
<label for="tp-fall" class="package-check-toggle">
<h4 class="tp-template-title">Fall</h4>
<img src="images/tp-fall.png" class="tp-template-img">
<img src="images/checkmark-circle.png" class="checkmark-img total-center">
</label>
<input type="checkbox" class="tp-template-check" data-template="Fall" data-template-image="<img src='images/tp-fall.png' class='review-img'>" id="tp-fall" value="Fall">
</div>
</div>
<div class="tp-template">
<div class="product-wrap">
<label for="tp-newYears" class="package-check-toggle">
<h4 class="tp-template-title">New Years</h4>
<img src="images/tp-newYears.png" class="tp-template-img">
<img src="images/checkmark-circle.png" class="checkmark-img total-center">
</label>
<input type="checkbox" class="tp-template-check" data-template="New Years" data-template-image="<img src='images/tp-newYears.png' class='review-img'>" id="tp-newYears" value="New Years">
</div>
</div>
<div class="tp-template">
<div class="product-wrap">
<label for="tp-independence" class="package-check-toggle">
<h4 class="tp-template-title">Independence Day</h4>
<img src="images/tp-independence.png" class="tp-template-img">
<img src="images/checkmark-circle.png" class="checkmark-img total-center">
</label>
<input type="checkbox" class="tp-template-check" data-template="Independence Day" data-template-image="<img src='images/tp-independence.png' class='review-img'>" id="tp-independence" value="Independence Day">
</div>
</div>
<div class="tp-template">
<div class="product-wrap">
<label for="tp-thanksgiving" class="package-check-toggle">
<h4 class="tp-template-title">Thanksgiving</h4>
<img src="images/tp-thanksgiving.png" class="tp-template-img">
<img src="images/checkmark-circle.png" class="checkmark-img total-center">
</label>
<input type="checkbox" class="tp-template-check" data-template="Thanksgiving" data-template-image="<img src='images/tp-thanksgiving.png' class='review-img'>" id="tp-thanksgiving" value="Thanksgiving">
</div>
</div>
Some of your if statement conditions seem to be incorrect. You encased the conditions like they were jQuery selectors.
Change this:
if ($(templateCount > 0)) {
...
}
if ($(templateCount >= limitTemplate)) {
...
}
To this:
if (templateCount > 0) {
...
}
if (templateCount >= limitTemplate) {
...
}
Related
I'm having trouble hiding data with jQuery.
I have several products and a filtering system in jQuery, I would like to hide filters that are not used on a given subpage, in my case, data-power.
I am extracting data that matches .product data-power, but now I don't know how to hide a value that is not listed in my 1200 case. Example:
$('.stat').on('click', function() {
var $stats = $('.stat:checked');
var $items = $('.list .product');
$items.show();
if ($stats.length == 0)
return;
var $vstats = $.map($stats, function(o) {
return $(o).data('id');
});
$stats.each(function() {
var $stat = $(this);
$items.filter(function() {
var $currentitem = $(this).data($stat.data('type'));
if ($currentitem.toString().indexOf(",") > -1) {
var $item = $currentitem.split(",");
var hit = 0;
$item.forEach(function(m) {
if ($vstats.indexOf(m) > -1) {
hit++;
}
});
if (hit > 0) {
return false;
} else {
return true;
}
} else {
if ($vstats.indexOf($currentitem) > -1) {
return false;
} else {
return true;
}
}
}).hide();
})
});
function onlyUnique(value, index, self) {
return self.indexOf(value) === index;
}
var array = [];
$('.product').each(function(i, e) {
array.push($(e).data('power'));
});
var unique = array.filter(onlyUnique);
unique.sort();
alert(unique);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="power">
<h2>power</h2>
<div class="checkbox">
<label>
<input data-id="750" data-type="power" class="stat power" type="checkbox">750 </label>
<label>
<input data-id="800" data-type="power" class="stat power" type="checkbox">800 </label>
<label>
<input data-id="1200" data-type="power" class="stat power" type="checkbox">1200 </label>
</div>
</div>
<div class="grill">
<h2>grill</h2>
<div class="checkbox">
<label>
<input data-id="yes" data-type="grill" class="stat grill" type="checkbox">yes </label>
<label>
<input data-id="no" data-type="grill" class="stat grill" type="checkbox">no </label>
</div>
</div>
<div class="list">
<div class="col-6 col-lg-3 product" data-power="750" data-grill="yes">
<a href="/href/freh">
<div class="product-page__container product-container text-center">
<div class="product-page__name">
<h2><span class="d-block">Product Name</span> Product 1</h2>
</div>
</div>
</a>
</div>
<div class="col-6 col-lg-3 product" data-power="800" data-grill="yes">
<a href="/href/freh">
<div class="product-page__container product-container text-center">
<div class="product-page__name">
<h2><span class="d-block">Product Name 2</span> Product 2</h2>
</div>
</div>
</a>
</div>
</div>
https://jsfiddle.net/x0atpcz4/1/
I would select the items you are to filter and grab the values. Then I would grab the filters and see if they exists and remove the ones that do not.
var powers = $('[data-power]').map(function (){ return this.dataset.power; }).get();
$('[data-id]').filter(function () {
return !powers.includes(this.dataset.id)
}).closest("label").hide();
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="power">
<h2>power</h2>
<div class="checkbox">
<label>
<input data-id="750" data-type="power" class="stat power" type="checkbox">750 </label>
<label>
<input data-id="800" data-type="power" class="stat power" type="checkbox">800 </label>
<label>
<input data-id="1200" data-type="power" class="stat power" type="checkbox">1200 </label>
</div>
</div>
<div class="list">
<div class="col-6 col-lg-3 product" data-power="750">
<a href="/href/freh">
<div class="product-page__container product-container text-center">
<div class="product-page__name">
<h2><span class="d-block">Product Name</span> Product 1</h2>
</div>
</div>
</a>
</div>
<div class="col-6 col-lg-3 product" data-power="800">
<a href="/href/freh">
<div class="product-page__container product-container text-center">
<div class="product-page__name">
<h2><span class="d-block">Product Name 2</span> Product 2</h2>
</div>
</div>
</a>
</div>
</div>
My javascript code doesnt seem to run when i use this codes to validate the radio button is clicked. Its suppose to dropdown the inputs when the card radio button is clicked and it is suppose to slide up the inputs when the paypal button is clicked.1st code javascript. 2nd code html.
if (document.getElementById('paypal').checked) {
//Paypal radio button is checked
$(".input-fields").slideDown("slow");
} else if (document.getElementById('card').checked) {
//Card radio button is checked
$(".input-fields").slideUp("slow");
};
<div class="panel-body">
<h2 class="title">Checkout</h2>
<div class="bar">
<div class="step active"></div>
<div class="step active"></div>
<div class="step"></div>
<div class="step"></div>
</div>
<div class="payment-method">
<label for="card" class="method card">
<div class="card-logos">
<img src="img/visa_logo.png" />
<img src="img/mastercard_logo.png" />
</div>
<div class="radio-input">
<input id="card" type="radio" name="payment"> Pay $<%= total %> with credit card
</div>
</label>
<label for="paypal" class="method paypal">
<img src="img/paypal_logo.png" />
<div class="radio-input">
<input id="paypal" type="radio" name="payment"> Pay $<%= total %> with PayPal
</div>
</label>
</div>
<div class="input-fields">
<div class="column-1">
<label for="cardholder">Cardholder's Name</label>
<input type="text" id="cardholder" />
<div class="small-inputs">
<div>
<label for="date">Valid thru</label>
<input type="text" id="date" placeholder="MM / YY" />
</div>
<div>
<label for="verification">CVV / CVC *</label>
<input type="password" id="verification" />
</div>
</div>
</div>
<div class="column-2">
<label for="cardnumber">Card Number</label>
<input type="password" id="cardnumber" />
<span class="info">* CVV or CVC is the card security code, unique three digits number on the back of your card separate from its number.</span>
</div>
</div>
</div>
All you missed was to add the logic inside a function and add it to an event using addEventListener() for value change.
We use document.getElementById() to get both the input elements by ID and then add the event listener to fire on change of value.
document.getElementById("card").addEventListener("change", validate);
document.getElementById("paypal").addEventListener("change", validate);
function validate() {
if (document.getElementById('paypal').checked) {
//Paypal radio button is checked
$(".input-fields").slideDown("slow");
} else if (document.getElementById('card').checked) {
//Card radio button is checked
$(".input-fields").slideUp("slow");
};
}
document.getElementById("card").addEventListener("change", validate);
document.getElementById("paypal").addEventListener("change", validate);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="panel-body">
<h2 class="title">Checkout</h2>
<div class="bar">
<div class="step active"></div>
<div class="step active"></div>
<div class="step"></div>
<div class="step"></div>
</div>
<div class="payment-method">
<label for="card" class="method card">
<div class="card-logos">
<img src="img/visa_logo.png" />
<img src="img/mastercard_logo.png" />
</div>
<div class="radio-input">
<input id="card" type="radio" name="payment"> Pay $<%= total %> with credit card
</div>
</label>
<label for="paypal" class="method paypal">
<img src="img/paypal_logo.png" />
<div class="radio-input">
<input id="paypal" type="radio" name="payment"> Pay $<%= total %> with PayPal
</div>
</label>
</div>
<div class="input-fields">
<div class="column-1">
<label for="cardholder">Cardholder's Name</label>
<input type="text" id="cardholder" />
<div class="small-inputs">
<div>
<label for="date">Valid thru</label>
<input type="text" id="date" placeholder="MM / YY" />
</div>
<div>
<label for="verification">CVV / CVC *</label>
<input type="password" id="verification" />
</div>
</div>
</div>
<div class="column-2">
<label for="cardnumber">Card Number</label>
<input type="password" id="cardnumber" />
<span class="info">* CVV or CVC is the card security code, unique three digits number on the back of your card separate from its number.</span>
</div>
</div>
</div>
References:
Event Listeners
You need to add your javascript inside an event listener. For Example
$("input[name='payment']").click(function ()
{
if (document.getElementById('paypal').checked)
{
//Paypal radio button is checked
$(".input-fields").slideDown("slow");
}
else if (document.getElementById('card').checked)
{
//Card radio button is checked
$(".input-fields").slideUp("slow");
}
;
});
I'm currently using jQuery Validator on a form of mine, when submitting my form it appears that the checked attribute isn't changing on my validator regardless of checked or unchecked.
Here's my HTML:
<div class="col-sm-10 col-sm-offset-1">
<div class="col-sm-6">
<div class="choice" data-toggle="wizard-radio">
<input type="radio" name="platform" value="P1">
<div class="icon">
<img src="{{ asset('images/platform1.png') }}" style="height: 100px;">
</div>
<h6>Platform 1</h6>
</div>
</div>
<div class="col-sm-6">
<div class="choice" data-toggle="wizard-radio">
<input type="radio" name="platform" value="P2">
<div class="icon">
<img src="{{ asset('images/platform2.png') }}" style="height: 100px;">
</div>
<h6>Platform2</h6>
</div>
</div>
<label for="platform" class="error" style="display:none;">Please choose one.</label>
</div>
Here's my JS:
// Code for the Validator
var $validator = $('.wizard-card form').validate({
rules: {
platform: {
required: function () {
var checked = false;
$('input[name="platform"]').each(function() {
if(jQuery(this)[0].hasAttribute('checked')) {
var checked = true;
}
});
console.log(checked);
return checked;
}
}
}
});
I've even tried just using return $('[name="platform"]:checked').length > 0; to no avail.
EDIT
Maybe you are over-complicating the task here...
That simple rule is supposed to work:
$('.wizard-card form').validate({
rules: {
platform: "required"
}
});
.error{
outline:3px solid red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-validate/1.17.0/jquery.validate.js"></script>
<div class="wizard-card">
<form>
<div class="col-sm-10 col-sm-offset-1">
<div class="col-sm-6">
<div class="choice" data-toggle="wizard-radio">
<input type="radio" name="platform" value="P1">
<div class="icon">
<img src="https://via.placeholder.com/350x150" style="height: 100px;">
</div>
<h6>Platform 1</h6>
</div>
</div>
<div class="col-sm-6">
<div class="choice" data-toggle="wizard-radio">
<input type="radio" name="platform" value="P2">
<div class="icon">
<img src="https://via.placeholder.com/350x150" style="height: 100px;">
</div>
<h6>Platform2</h6>
</div>
</div>
<label for="platform" class="error" style="display:none;">Please choose one.</label>
</div>
<button id="done">Submit</button>
</form>
</div>
I suggest you read the documentation a bit more closely.
I've been trying to use the jquery parentsUntil method to hide a button until a radio box is selected, but I can't seem to get it to work. It's probably something obvious, but it's been bugging me for a couple of days now. Can anyone see what I'm doing wrong.
(function($) {
$(function(){
$('.last-item').change(function() {
if( $(this).val() != '' ) {
$(this).parentsUntil('.step').find('.button-next').removeClass('hide');
$(this).parentsUntil('.step').find('.button-next').addClass('show');
console.log("changing the last item");
}
});
});
})(jQuery);
.hide {
display: none;
}
.show {
display: block !important;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<div class="step">
<h1>Step 3 - Personal</h1>
<div class="input-wrapper radio no-feedback">
<div class="row no-gutter content-position-outer">
<div class="col-md-6 content-center-inner">
<label for="gender">What gender are you? <sup>*</sup></label>
</div>
<div class="col-md-6 content-center-inner">
<div class="row">
<div class="col-md-5 col-md-offset-2">
<label class="radio-sex" for="gender_male">
<input class="sr-only last-item" type="radio" placeholder="Male" name="gender" value="Male" id="gender_male" required="required" />
<div class="radio-img radio-img-sex-male"></div>
Male
</label>
</div>
<div class="col-md-5">
<label class="radio-sex" for="gender_female">
<input class="sr-only last-item" type="radio" placeholder="Female" name="gender" value="Female" id="gender_female" required="required" />
<div class="radio-img radio-img-sex-female"></div>
Female
</label>
</div>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-md-3">
Previous
</div>
<div class="col-md-3 col-md-push-6">
Next
</div>
</div>
</div>
JS Fiddle
.parentsUntil() gets "the ancestors of each element in the current set of matched elements, up to but not including the element matched by the selector,".
Try .closest() instead
This is likely what you meant?
No need to hide if value is empty since you cannot deselect a radio.
If you want to hide when some value is empty, use .toggle($(this).val()!="")
(function($) {
$(function() {
$('.last-item').on("click",function() { // click assumes radio as last item
$(this).closest("div.step").find('.button-next').show();
});
});
})(jQuery);
.button-next { display:none }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="step">
<h1>Step 3 - Personal</h1>
<div class="input-wrapper radio no-feedback">
<div class="row no-gutter content-position-outer">
<div class="col-md-6 content-center-inner">
<label for="gender">What gender are you? <sup>*</sup>
</label>
</div>
<div class="col-md-6 content-center-inner">
<div class="row">
<div class="col-md-5 col-md-offset-2">
<label class="radio-sex" for="gender_male">
<input class="sr-only last-item" type="radio" placeholder="Male" name="gender" value="Male" id="gender_male" required="required" />
<div class="radio-img radio-img-sex-male"></div>
Male
</label>
</div>
<div class="col-md-5">
<label class="radio-sex" for="gender_female">
<input class="sr-only last-item" type="radio" placeholder="Female" name="gender" value="Female" id="gender_female" required="required" />
<div class="radio-img radio-img-sex-female"></div>
Female
</label>
</div>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-md-3">
Previous
</div>
<div class="col-md-3 col-md-push-6">
Next
</div>
</div>
</div>
Try this snippet. I hope it will work
Note:remove hide class from -> class="button-next hide"
$(function(){
$('.button-next').hide();
$('input[type="radio"]').click(function() {
if($(this).prop('checked') == true) {
$('.button-next').show();
}
else {
$('.button-next').hide();
}
});
});
All good sensible answers, guys, but none of them worked for me. In the end I had to use
$(this).closest('.step-3').find('.button-next').css('display','block');
I have the following Checklist and Tasks Structure
Now i want if any one checks a Task i want to make sure the the Checklist also gets checked.
When someone unchecks the checklist all the tasks should get unchecked.
<!-- Checklist -->
<div class="checklist">
<div class="media">
<div class="pull-left checklist-checkbox">
<input class="checklist-input" name="checklist" type="checkbox" value="">
</div>
<div class="media-body task-list">
<h4 class="media-heading">This is a CheckList</h4>
<div class="media tasks">
<div class="pull-left task-checkbox">
<input class="task-input" name="task" type="checkbox" value="">
</div>
<div class="media-body">Search for entertainers that perform the types of shows that are suitable for your function.</div>
</div>
<div class="media tasks">
<div class="pull-left task-checkbox">
<input class="task-input" name="task" type="checkbox" value="">
</div>
<div class="media-body"> Book your venue.</div>
</div>
<div class="media tasks">
<div class="pull-left task-checkbox">
<input class="task-input" name="task" type="checkbox" value="">
</div>
<div class="media-body"> Search for a caterer that is suitable for your function. <span class="label label-default">Lalu - June 23rd, 2014</span></div>
</div>
<div class="media tasks">
<div class="pull-left task-checkbox">
<input class="task-input" name="task" type="checkbox" value="">
</div>
<div class="media-body"> Hold a training session for all attending staff and brief them on all activities and expectations for the day of the event.</div>
</div>
<div class="media tasks">
<div class="pull-left task-checkbox">
<input class="task-input" name="task" type="checkbox" value="">
</div>
<div class="media-body"> Appoint an adequate number of staff as greeters to welcome guests and orient them with the event activities and venue.</div>
</div>
<div class="add-task">Add Task</div>
<div class="form-add-task">
<form action="addtask.php" method="post">
<input type="text" class="form-control task-input">
<input class="btn btn-sm btn-default" name="submit-task" type="submit" value="Add Task">
</form>
</div>
</div>
</div>
</div>
<div class="checklist">
<div class="media">
<div class="pull-left checklist-checkbox">
<input class="checklist-input" name="checklist" type="checkbox" value="">
</div>
<div class="media-body task-list">
<h4 class="media-heading">This is a CheckList</h4>
<div class="media tasks">
<div class="pull-left task-checkbox">
<input class="task-input" name="task" type="checkbox" value="">
</div>
<div class="media-body">Search for entertainers that perform the types of shows that are suitable for your function.</div>
</div>
<div class="media tasks">
<div class="pull-left task-checkbox">
<input class="task-input" name="task" type="checkbox" value="">
</div>
<div class="media-body"> Book your venue.</div>
</div>
<div class="media tasks">
<div class="pull-left task-checkbox">
<input class="task-input" name="task" type="checkbox" value="">
</div>
<div class="media-body"> Search for a caterer that is suitable for your function. <span class="label label-default">Lalu - June 23rd, 2014</span></div>
</div>
<div class="media tasks">
<div class="pull-left task-checkbox">
<input class="task-input" name="task" type="checkbox" value="">
</div>
<div class="media-body"> Hold a training session for all attending staff and brief them on all activities and expectations for the day of the event.</div>
</div>
<div class="media tasks">
<div class="pull-left task-checkbox">
<input class="task-input" name="task" type="checkbox" value="">
</div>
<div class="media-body"> Appoint an adequate number of staff as greeters to welcome guests and orient them with the event activities and venue.</div>
</div>
<div class="add-task">Add Task</div>
<div class="form-add-task">
<form action="addtask.php" method="post">
<input type="text" class="form-control task-input">
<input class="btn btn-sm btn-default" name="submit-task" type="submit" value="Add Task">
</form>
</div>
</div>
</div>
</div>
<!-- / Checklist -->
jQuery Code:
$('input.checklist-input').on('change',function(){
$(this).parent().siblings('.task-list').find('input.task-input').prop('checked',$(this).prop('checked'));
})
Similar to Caio Vianna, just a different if, and targeting the proper list. Also added the unchecking of checklist if there's no longer any checked tasks. I'm sure you can optimize the selectors though, anyways should be helpful
$('input.task-input').on('change', function () {
if ($(this).prop('checked') === true) {
$(this).closest('div.tasks').parent().prev().find('input.checklist-input').prop('checked', true);
} else {
var checked = $(this).closest('div.task-list').find('input.task-input:checked').length;
if (checked === 0) {
$(this).closest('div.tasks').parent().prev().find('input.checklist-input').prop('checked', false);
}
}
})
I believe you are lacking the function that does the following logic:
Listen to the change event on .task-input
Determine if the length of checked items of grouped .task-input elements exceeds 0
If it exceeds zero, check the group's own .checklist-input
If not, uncheck the group's own .checklist-input
And here is the missing function:
$('input.task-input').on('change', function() {
var tasks = $(this).closest('.task-list').find('input.task-input:checked').length;
$(this).closest('.checklist').find('input.checklist-input').prop('checked',tasks);
});
Proof-of-concept fiddle: http://jsfiddle.net/teddyrised/1cy47tga/1/
Your code will check everything (or not) as the master checklist is toggled (alas, when you check it, it will check everything inside, and vice versa).
You want to test that first so ...
$('input.checklist-input').on('change',function(){
if (!$(this).prop('checked'))
$(this).parent().siblings('.task-list').find('input.task-input').prop('checked',false);
})
That will only UNCHECK, since it only runs if you unchecked the master checklist.
As for the rest
$(input.task-input').on('change',function() {
if ($(this).prop('checked'))
$('input.checklist-input').prop('checked',true);
})
Will check the master checklist only if you checked a sibling
Note: my jquery selector skills are rusty, so I might made some mistake there, but I guess the logic of the thing isclear =p
You should take control in two steps:
For the main level checklist button:
$('body').on('change', '.checklist-input', function () {
var checked = $(this).prop('checked');
$(this).closest('.checklist').find('.task-input:checkbox').prop('checked', checked);
});
For the second level checkboxes:
$('body').on('change', '.task-input:checkbox', function () {
var checkedArray = [];
var $checkboxes = $(this).closest('.checklist').find('.task-input:checkbox');
$checkboxes.each(function () {
var checked = $(this).prop('checked');
if (checked) {
checkedArray.push(checked);
}
});
var totalChecked = false;
if (checkedArray.length == $checkboxes.length) {
totalChecked = true;
}
$(this).closest('.checklist').find('.checklist-input').prop('checked', totalChecked);
});
JSFiddle Demo.