Skip to content

Instantly share code, notes, and snippets.

@keyo
Created June 22, 2012 05:01
Show Gist options
  • Save keyo/2970340 to your computer and use it in GitHub Desktop.
Save keyo/2970340 to your computer and use it in GitHub Desktop.
jQuery Field Dependencies

jQuery Field Dependencies

Author: Ben Brady Licensed: MIT

Overview

Allows selected elements to be changed (shown/hidden or callback) based on a set of field validation rules.

This is useful for large forms where you may want to hide/disable various fieldsets which are relevant only if a particular input element is selected/checked.

Options

rules

An array of rule objects, each rule object has the following properties:

  • field (required): A required field selector e.g. "input#email", "input[name=password]"

  • validate (optional):

  • Not specified, rule valid if field value is not undefined

  • string, field value is equal to the specified string.

  • function, called with first argument set to the rule.field selector. To validate return true.

     	[
     		{ field: "input[name=email]}, // an email field is not undefined.
     		{ field: "input[name=password"], 
     			validate: function(field) { if ($(field).val() != "12345") return true; }  // password is not 12345
     		} 
     	}]
    

ruleLogic (optional)

  • 'any' default - at least one rule must validate (OR logic)
  • 'all' - all the rules must validate (AND logic)

onValid (optional)

Callback function, default hides the element(s) and disables child fields. Called with first argument = $(this).

function(dependent_elements) { $(dependent_elements).show(); }

onInvalid (optional)

Callback function, default shows the element(s) and enables child fields. Called with first argument = $(this).

function(dependent_elements) { $(dependent_elements).hide(); }

Known Issues

  • May call onValid/onInvalid events mutiple times if an element has several dependencies. Not great for visual effects.
  • Only uses .change() event to bind fields to validation.

Example

	<fieldset>
		<p>How do you get to work?</p>
		<p><input type="radio" name="transport" value="bike" />Bike</p>
		<p><input type="radio" name="transport" value="car" />Car</p>
	</fieldset>
	<fieldset id="car"><label for="fuel">How much fuel do you use a day?</label><input id="fuel" type="number" name="fuel">Litres</fieldset>
	<fieldset id="bike"><label for="fuel">Do you wear a helmet?</label><input id="fuel" type="checkbox" name="helmet"></fieldset>

	<script>
		var rule_car = {field:"input[name=transport]", 
		validate: "car"};
		$("#car").dependsOn({
			rules: [rule_car],
			onValid: function(elemenets) { 
				// elements is set to the jQuery object: $(#car)
				alert("Nice car");
				$(elements).css("background":"pink"); 
			}
		});
	</script>
/*
Form Dependency Plugin
======================
Allows for elements to be shown/hidden based on a set of field validation rules.
See README.md for documentation.
Author: Ben Brady
Licensed: MIT
*/
(function ($) {
$.fn.dependsOn = function (opts) {
var elements = this;
var defaults = {
rules: [], // each rule is an object with a field and optional validate function or string
ruleLogic: "all", // any: at least one rule must pass // all : all rules need to be true
onValid: function (elems) {
$(elems).show();
$(elems).find(':input').attr("disabled", false);
},
onInvalid: function (elems) {
$(elems).hide();
$(elems).find(':input').attr("disabled", true);
}
};
opts = $.extend(defaults, opts);
var validate_rules = function () {
var valid = 0;
var invalid = 0;
$.each(opts.rules, function (ix, rule) {
if (rule.validate == undefined) {
//no validation function string match value means we just check if the field value is not empty.
rule.validate = function (field) {
var val;
if($(field + ':not(:disabled)').length == 0) {
return true;
}
if ($(field).is('input[type=checkbox], input[type=radio]')) {
val = $(field + ':not(:disabled):checked').val();
} else {
val = $(field + ":not(:disabled)").val();
}
if (val != undefined) {
return true;
};
return false;
}
}
if (typeof (rule.validate) === 'string') {
// strings mean we just compare the value directly
var match_string = rule.validate;
rule.validate = function (field) {
var val;
if ($(field).is('input[type=checkbox], input[type=radio]')) {
val = $(field + ':not(:disabled):checked').val();
} else {
val = $(field + ":not(:disabled)").val();
}
if (val === match_string) {
return true;
};
return false;
}
}
var isValid = rule.validate(rule.field);
if (isValid) {
valid++;
} else {
invalid++;
}
});
if (opts.ruleLogic == "all" && invalid > 0) {
opts.onInvalid(elements);
} else if (opts.ruleLogic == "any" && valid == 0) {
opts.onInvalid(elements);
}
else {
opts.onValid(elements);
}
}
// Bind events
$.each(opts.rules, function (index, rule) {
$(rule.field).change(function () {
validate_rules();
});
});
// Initial validation, usually done on page load
validate_rules();
// Don't break the chain!
return this;
};
})(jQuery);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment