views:

90

answers:

3

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? :)

+1  A: 

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.

xar
thanks xar, but assigning a value based on another input status is not really what i want.
Alex
+3  A: 

Here you go :-)

http://jsfiddle.net/264Yd/7/


(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>
balupton
thanks you. you did a amazing job! the only problem is that input.dependsOn(radio=value) doesn't seem to work
Alex
Will look into it :)
balupton
Fixed: http://jsfiddle.net/264Yd/7/
balupton
nice :D I love you :D
Alex