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
- 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. - 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
精彩评论