开发者

How to create a dynamic form using jQuery?

I've seen a lot of help for dynamically adding rows or fields, but I'm interested in controlling fields that are dependent on one another.

For example, I have a form with 3 user inputs:开发者_如何学C

<select id="foo">
  <option value="0">No</option>
  <option value="1">Yes</option>
</select>

When #foo's value is set to 1, I'd like to enable #bar.

<!-- by default, bar should be disabled -->
<select id="bar">
  <option value="something_1">Something 1</option>
  <option value="something_2">Something 2</option>
  <option value="other">Other...</option>
</select>

When #bar's value is set to other, I'd like to enable #baz.

<!-- by default, baz should be disabled -->
<textarea id="baz"></textarea>

My Goal

I'd like to some guidance on writing a small plugin that allows easy creation of form inputs with dependencies.

I'd like short, concise syntax. Is there a way I could add html attribute helpers to aid the jQuery plugin in "automating" things?

Foreseeable Issues

  1. If #foo is set to "Yes", then #bar is set to "other", then #foo is set to "No", I will want #bar's dependencies deactivated/hidden as well.
  2. Inputs are enabled/disabled and/or visible/hidden; Having the ability to define custom behaviors for elements would be nice.

Reinventing the Wheel

If there's a plugin out there that does this kind of thing, let me know! I couldn't seem to find one...


You'll want to focus on event handling on the .change() event as your entry point. The handler can look up the form element id and value in a JSON structure to decide what, if any, actions need to happen. The javascript might look like this:

form = {"input1" : 
    {"value1": {
        /*action list */
        [{"hide": ["input2", "input3"], "show": ["input4"], "set": {"input5": "True", "input6": "False"}]
    },
    "value2": {[/* another set of actions */]}
}


function onchange(e) {
    id = $(this).attr("id");
    value = $(this).val();
    if (id in form) {
        if (value in form[id]) {
            $.each(form[id][value], function(i, action) {
                if ("hide" in action) { $(action).hide(); }
                /* etc for other actions */
            });
        }
    }
}

$(document).ready(function() {$("input").change(onchange);}


A quick plugin

(function($){

  $.fn.inputDependsOn = function(id, values, options){

    var self = this;

    // methods
    this.disable = function(e){
      return e.addClass(options.cssClass).attr({disabled: true}).trigger("disable");
    };

    this.enable = function(e){
      return e.removeClass(options.cssClass).attr({disabled: null}).trigger("enable");
    };

    // options
    options = $.extend({}, $.fn.dependsOn.defaults, options || {});

    var parent = $(id);

    this.each(function(){
      var child = $(this);

      // parent binds
      parent
        .bind("change", function(){
          var v = parent.val();
          if(parent.is(":not(:disabled)") && v in values){
            self[values[v]](child);
          }
          else {
            self[options.init](child);
          }
          child.change();
        })
        .bind("disable", function(){
          self.disable(child);
        })
      ;
    });

    // init
    parent.change();
    return this;
  };

  $.fn.dependsOn.defaults = {
    init: "disable",
    cssClass: "disabled"
  };

})(jQuery);

Using the HTML in the original question, goal can be accomplished with:

$("#bar").inputDependsOn("#foo", {"1": "enabled"});
$("#baz").inputDependsOn("#bar", {"other": "enable"});

This plugin will be maintained and update here:

github.com/macek/jquery-input-depends-on

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜