Skip to content

Instantly share code, notes, and snippets.

@robdmoore
Last active August 29, 2015 14:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save robdmoore/4afd81d5fe22ccc7d61f to your computer and use it in GitHub Desktop.
Save robdmoore/4afd81d5fe22ccc7d61f to your computer and use it in GitHub Desktop.
Foolproof validation with show/hide
$(function() {
$("form").each(function() {
$(this).find("[data-val-requiredif]").each(function() {
var $field = $(this);
var comparisonValue = $field.data("val-requiredif-dependentvalue");
var operator = $field.data("val-requiredif-operator");
var passonnull = $field.data("val-requiredif-passonnull");
var dependentPropertyName = $field.data("val-requiredif-dependentproperty");
var dependentProperties = $("[name=" + dependentPropertyName + "]");
var change = function () {
var dependentValue;
if (dependentProperties.size() > 1) {
dependentValue = dependentProperties.filter(":checked").val() || false;
} else {
dependentValue = dependentProperties.val();
}
if (foolproof.is(dependentValue, operator, comparisonValue, passonnull)) {
$field.closest(".form-group").show();
}
else {
$field.closest(".form-group").hide();
if ($field.is(":checkbox,:radio")) {
$field.closest(".form-group").find("input").attr("checked", null).change();
} else if ($field.is("div")) {
$field.find("input,select,textarea").each(function() {
var $innerField = $(this);
if ($innerField.is(":checkbox,:radio"))
$innerField.attr("checked", null).change();
else
$innerField.val("").change();
};
} else {
$field.val("").change();
}
}
});
dependentProperties.change(change).keyup(change);
change();
});
});
});
var foolproof = function () { };
foolproof.is = function (value1, operator, value2, passOnNull) {
if (passOnNull) {
var isNullish = function (input) {
return input == null || input == undefined || input == "";
};
var value1nullish = isNullish(value1);
var value2nullish = isNullish(value2);
if ((value1nullish && !value2nullish) || (value2nullish && !value1nullish))
return true;
}
var isNumeric = function (input) {
return (input - 0) == input && input.length > 0;
};
var isDate = function (input) {
var dateTest = new RegExp(/(?=\d)^(?:(?!(?:10\D(?:0?[5-9]|1[0-4])\D(?:1582))|(?:0?9\D(?:0?[3-9]|1[0-3])\D(?:1752)))((?:0?[13578]|1[02])|(?:0?[469]|11)(?!\/31)(?!-31)(?!\.31)|(?:0?2(?=.?(?:(?:29.(?!000[04]|(?:(?:1[^0-6]|[2468][^048]|[3579][^26])00))(?:(?:(?:\d\d)(?:[02468][048]|[13579][26])(?!\x20BC))|(?:00(?:42|3[0369]|2[147]|1[258]|09)\x20BC))))))|(?:0?2(?=.(?:(?:\d\D)|(?:[01]\d)|(?:2[0-8])))))([-.\/])(0?[1-9]|[12]\d|3[01])\2(?!0000)((?=(?:00(?:4[0-5]|[0-3]?\d)\x20BC)|(?:\d{4}(?!\x20BC)))\d{4}(?:\x20BC)?)(?:$|(?=\x20\d)\x20))?((?:(?:0?[1-9]|1[012])(?::[0-5]\d){0,2}(?:\x20[aApP][mM]))|(?:[01]\d|2[0-3])(?::[0-5]\d){1,2})?$/);
return dateTest.test(input);
};
var isBool = function (input) {
return input === true || input === false || input === "true" || input === "True" || input === "false" || input === "False";
};
if (isDate(value1)) {
value1 = Date.parse(value1);
value2 = Date.parse(value2);
}
else if (isBool(value1)) {
if (value1 == "false" || value1 == "False") value1 = false;
if (value2 == "false" || value2 == "False") value2 = false;
value1 = !!value1;
value2 = !!value2;
}
else if (isNumeric(value1)) {
value1 = parseFloat(value1);
value2 = parseFloat(value2);
}
switch (operator) {
case "EqualTo": if (value1 == value2) return true; break;
case "NotEqualTo": if (value1 != value2) return true; break;
case "GreaterThan": if (value1 > value2) return true; break;
case "LessThan": if (value1 < value2) return true; break;
case "GreaterThanOrEqualTo": if (value1 >= value2) return true; break;
case "LessThanOrEqualTo": if (value1 <= value2) return true; break;
case "RegExMatch": return (new RegExp(value2)).test(value1); break;
case "NotRegExMatch": return !(new RegExp(value2)).test(value1); break;
}
return false;
};
foolproof.getId = function (element, dependentPropety) {
var pos = element.id.lastIndexOf("_") + 1;
return element.id.substr(0, pos) + dependentPropety.replace(/\./g, "_");
};
foolproof.getName = function (element, dependentPropety) {
var pos = element.name.lastIndexOf(".") + 1;
return element.name.substr(0, pos) + dependentPropety;
};
(function () {
jQuery.validator.addMethod("is", function (value, element, params) {
var dependentProperty = foolproof.getId(element, params["dependentproperty"]);
var operator = params["operator"];
var passOnNull = params["passonnull"];
var dependentValue = document.getElementById(dependentProperty).value;
if (foolproof.is(value, operator, dependentValue, passOnNull))
return true;
return false;
});
jQuery.validator.addMethod("requiredif", function (value, element, params) {
var dependentProperty = foolproof.getName(element, params["dependentproperty"]);
var dependentTestValue = params["dependentvalue"];
var operator = params["operator"];
var pattern = params["pattern"];
var dependentPropertyElement = document.getElementsByName(dependentProperty);
var dependentValue = null;
if (dependentPropertyElement.length > 1) {
for (var index = 0; index != dependentPropertyElement.length; index++)
if (dependentPropertyElement[index]["checked"]) {
dependentValue = dependentPropertyElement[index].value;
break;
}
if (dependentValue == null)
dependentValue = false
}
else
dependentValue = dependentPropertyElement[0].value;
if (foolproof.is(dependentValue, operator, dependentTestValue)) {
if (pattern == null) {
if (value != null && value.toString().replace(/^\s\s*/, '').replace(/\s\s*$/, '') != "")
return true;
}
else
return (new RegExp(pattern)).test(value);
}
else
return true;
return false;
});
jQuery.validator.addMethod("requiredifempty", function (value, element, params) {
var dependentProperty = foolproof.getId(element, params["dependentproperty"]);
var dependentValue = document.getElementById(dependentProperty).value;
if (dependentValue == null || dependentValue.toString().replace(/^\s\s*/, '').replace(/\s\s*$/, '') == "") {
if (value != null && value.toString().replace(/^\s\s*/, '').replace(/\s\s*$/, '') != "")
return true;
}
else
return true;
return false;
});
jQuery.validator.addMethod("requiredifnotempty", function (value, element, params) {
var dependentProperty = foolproof.getId(element, params["dependentproperty"]);
var dependentValue = document.getElementById(dependentProperty).value;
if (dependentValue != null && dependentValue.toString().replace(/^\s\s*/, '').replace(/\s\s*$/, '') != "") {
if (value != null && value.toString().replace(/^\s\s*/, '').replace(/\s\s*$/, '') != "")
return true;
}
else
return true;
return false;
});
var setValidationValues = function (options, ruleName, value) {
options.rules[ruleName] = value;
if (options.message) {
options.messages[ruleName] = options.message;
}
};
var $Unob = $.validator.unobtrusive;
$Unob.adapters.add("requiredif", ["dependentproperty", "dependentvalue", "operator", "pattern"], function (options) {
var value = {
dependentproperty: options.params.dependentproperty,
dependentvalue: options.params.dependentvalue,
operator: options.params.operator,
pattern: options.params.pattern
};
setValidationValues(options, "requiredif", value);
});
$Unob.adapters.add("is", ["dependentproperty", "operator", "passonnull"], function (options) {
setValidationValues(options, "is", {
dependentproperty: options.params.dependentproperty,
operator: options.params.operator,
passonnull: options.params.passonnull
});
});
$Unob.adapters.add("requiredifempty", ["dependentproperty"], function (options) {
setValidationValues(options, "requiredifempty", {
dependentproperty: options.params.dependentproperty
});
});
$Unob.adapters.add("requiredifnotempty", ["dependentproperty"], function (options) {
setValidationValues(options, "requiredifnotempty", {
dependentproperty: options.params.dependentproperty
});
});
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment