jQuery checkbox/radiobutton dependence plugin
I have made a small jQuery plugin that enables you to have checkboxes and radiobuttons that depends on each other in a nested way.
The usage is very simple, just take a collection of radios or checkboxes and define an element they depend on. If you check an element that depends on something, the parent will be checked as well.
In the same way, if you uncheck a parent element that have children, then the children will be unchecked as well.
The plugin is designed to also work with jQuery UI buttons
$('#fruitlist>li>input').dependsOn('#fruits');
$('#citruslist input').dependsOn('#citrus');
<ul> <li><input type="radio" name="products" value="books">books</li> <li><input type="radio" name="products" id="fruits" value="fruits">fruits <ul id="fruitlist"> <li><input type="checkbox">apples</li> <li><input type="checkbox" id="citrus">citrus fruits <ul id="citruslist"> <li><input type="radio" name="citrus">lemons</li> <li><input type="radio" name="citrus">oranges</li> </ul> </li> </ul> </li> <li><input type="radio" name="products" value="pens">pens</li> </ul>
Demo:
- books
-
fruits
- apples
-
citrus fruits
- lemons
- oranges
- pens
Here is the code:
/* jQuery checkbox/radiobutton dependance plugin
* By Martin Hansen http://martinhansen.no
* MIT Licensed.
*/
(function($) {
$.fn.dependsOn = function(parent) {
// build main options before element iteration
if(parent === undefined){ console.log('Parent is required'); return; }
var opts = {parent: parent, value: null};
//If parent is a radiobutton part of a group, make the group the parent
if($(opts.parent).attr('type') == 'radio'){
opts.origparent = $(opts.parent);
opts.parent = 'input[name=' +$(opts.parent).attr('name') +']';
}
return this.each(function() {
var caller = $(this);
$.data(this, 'dependsOnOptions', opts);//Store the dependency options
caller.bind('click iterate', function(event){
var parent = (opts.origparent) ? opts.origparent : $(opts.parent);
parent.attr('checked', true).trigger('iterate', ['Iterate', 'Event']);
if (jQuery.ui)parent.button('refresh'); //If jquery ui is loaded try to refesh button
});
$(opts.parent).each(function(i){
var pp = $(this);
//Do first time checks
var checked = pp.attr('checked');
if(checked){
$.fn.dependsOn.check(pp, caller, opts);
}
//bind for change
pp.change(function(event){
$.fn.dependsOn.check($(this), caller, opts);
});
});
});
};
$.fn.dependsOn.check = function(parent, child, opts){
if (!parent.is(':checked') || !$(opts.origparent).is(':checked')) {
child.attr('checked', false).change(); //uncheck the checked child, and trigger the change event so that any potential grandchildren also gets updated
if (jQuery.ui)parent.button('refresh'); //If jquery ui is loaded try to refesh button
}
};
})(jQuery);
On github: https://github.com/mokkabonna/jQuery-dependency
Edit:updated the code to use .is(‘:checked’) instead of .attr(‘checked’), as jQuery 1.6.3 returns ‘checked’ instead of true. Thanks to “all” in the comments for making me aware of if.