I'm searching for a jQuery plugin that does this.
for example:
<label><input type="checkbox" depends_on="foo=5" name="boo" ... /> Check </label>
<select name="foo" ... >
<option value="5" selected="selected">5</option>
<option value="15">15</option>
<option value="25">25</option>
</select>
so the checkbox would only be enabled if the "5" option is selected below.
or
<select name="foo" depends_on="boo" ... >
<option value="5" selected="selected">5</option>
<option value="15">15</option>
<option value="25">25</option>
</select>
<label><input type="checkbox" name="boo" ... /> Check </label>
In this case the select should only enabled if "boo" is checked.
I managed to come up with a code that does something like this:
$("*[depends_on]").each(function(){
var source = $(this);
var dep = $(this).attr('depends_on');
var target = dep.split("=");
$("*[name='"+target[0]+"']:not(:hidden)").change(function(){
if($(this).attr('checked')) {
source.removeClass('disabled');
source.removeAttr('disabled');
}
else{
source.attr('disabled', 'disabled');
source.addClass('disabled');
}
}).change();
});
seems to work ok for selects that depend on radios, but I want to implement this for any type of input or combination (or at least most of them), without having to write separate code for each type of input.
anyway, is anyone aware of such a plugin? or maybe have suggestions to my code above? :)
Here you go :-)
http://jsfiddle.net/balupton/cxcmf/
(function($){
/**
* jQuery.fn.dependsOn
* @version 1.0.1
* @date September 22, 2010
* @since 1.0.0, September 19, 2010
* @package jquery-sparkle {@link http://www.balupton/projects/jquery-sparkle}
* @author Benjamin "balupton" Lupton {@link http://www.balupton.com}
* @copyright (c) 2010 Benjamin Arthur Lupton {@link http://www.balupton.com}
* @license Attribution-ShareAlike 2.5 Generic {@link http://creativecommons.org/licenses/by-sa/2.5/
*/
$.fn.dependsOn = function(source,value){
var $target = $(this),
$source = $(source),
source = $source.attr('name')||$source.attr('id');
// Add Data
var dependsOnStatus = $target.data('dependsOnStatus')||{};
dependsOnStatus[source] = false;
$target.data('dependsOnStatus',dependsOnStatus);
// Add Event
$source.change(function(){
var pass = false;
var $source = $(this); // so $source won't be a group for radios
// Determine
if ( (value === null) || (typeof value === 'undefined') ) {
// We don't have a value
if ( $source.is(':checkbox,:radio') ) {
pass = $source.is(':selected:enabled,:checked:enabled');
}
else {
pass = Boolean($source.val());
}
}
else {
// We do have a value
if ( $source.is(':checkbox,:radio') ) {
pass = $source.is(':selected:enabled,:checked:enabled') && ($source.val() == value);
}
else {
pass = $source.val() == value;
}
}
// Update
var dependsOnStatus = $target.data('dependsOnStatus')||{};
dependsOnStatus[source] = pass;
$target.data('dependsOnStatus',dependsOnStatus);
// Determine
var passAll = true;
$.each(dependsOnStatus, function(i,v){
if ( !v ) {
passAll = false;
return false; // break
}
});
// console.log(dependsOnStatus);
// Adjust
if ( !passAll ) {
$target.attr('disabled','disabled').addClass('disabled');
}
else {
$target.removeAttr('disabled').removeClass('disabled');
}
}).trigger('change');
// Chain
return this;
};
})(jQuery);
For an example:
Javascript:
$(function(){
$('#foo').dependsOn('#boo').dependsOn('#moo','test')
.dependsOn(":radio[name=doo]",'true');
});
HTML:
<div>
<select name="foo" id="foo" >
<option value="5" selected="selected">5</option>
<option value="15">15</option>
<option value="25">25</option>
</select>
<input type="text" name="moo" id="moo" />
<input type="checkbox" name="boo" id="boo" />
<input type="radio" name="doo" value="false" />
<input type="radio" name="doo" value="true" />
<br/>
Type test in the textbox and check the checkbox to enable the select.
<br/>
By <a href="http://www.balupton.com" target="_blank">Benjamin "balupton" Lupton</a>, for <a href="http://stackoverflow.com/q/3731586/130638" target="_blank">a StackOverflow Question</a>
</div>
I've come up with this code :
$("input[target]").change(function(){
var target = $("[name='"+$(this).attr("target")+"']");
if($(this).is(":checked")){
target.attr("oldvalue",target.val()).val($(this).val());
}else{
target.val(target.attr("oldvalue"));
}
});
$("select").change(function(){
$("[target='"+ $(this).attr("name") +"'][value='"+ $(this).val() +"']").attr('checked', true);
});
And for the HTML format :
<label><input type="checkbox" target="foo" value="15"/> Check </label>
<select name="foo">
<option value="5" selected="selected">5</option>
<option value="15">15</option>
<option value="25">25</option>
</select>
So basically, all you have to do is to have a "target" attribute on an input, which should match the "name" attribute of the dropdown that you want to bind to. Set the value of the input too, which should select the value of its corresponding dropdown when it's checked.
jQuery disable button (NOT Submit) until field validates + Validation Plugin
jQuery enable/disable show/hide button w/ SELECT options. Get remaining option values
jQuery disable SELECT options based on Radio selected (Need support for all browsers)