Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

jQuery - disable input field based on another field selected value

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

like image 201
Alex Avatar asked Sep 16 '10 23:09

Alex


2 Answers

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>
like image 144
balupton Avatar answered Sep 22 '22 13:09

balupton


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.

like image 23
xar Avatar answered Sep 21 '22 13:09

xar